<?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=Glbrook2</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=Glbrook2"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Glbrook2"/>
	<updated>2026-07-13T21:15:44Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=142159</id>
		<title>CSC/ECE 517 Fall 2021 - E2150. Integrate suggestion detection algorithm</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=142159"/>
		<updated>2021-11-30T01:15:31Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Important Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem Definition ==&lt;br /&gt;
Peer-review systems like Expertiza utilize a lot of students’ input to determine each other’s performance. At the same time, students learn from the reviews they receive to improve their own performance. In order to make this happen, it would be good to have everyone give quality reviews instead of generic ones. Currently, Expertiza has a few classifiers that can detect useful features of review comments, such as whether they contain suggestions. The suggestion-detection algorithm has been coded as a web service, and other detection algorithms, such as problem detection and sentiment analysis, also exist as newer web services. We need to make the UI more intuitive by allowing users to view the feedback of specific review comments and the code needs to be refactored to remove redundancy to follow the DRY principle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Previous Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The previous implementation added the following features:&lt;br /&gt;
# Setup a config file 'review_metric.yml' where the instructor can select what review metric to display for the current assignments&lt;br /&gt;
# API calls (sentiment, problem, suggestion) are made and a table is rendered below, displaying the feedback of the review comments.&lt;br /&gt;
# The total time taken by the API calls was also displayed.&lt;br /&gt;
&lt;br /&gt;
=== UI Screenshots ===&lt;br /&gt;
The following image shows how a reviewer interacts with the system to get feedback on the review comments.&lt;br /&gt;
[[File:Steps_metric.png|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Control Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Review_metric.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Issues with Previous Work ==&lt;br /&gt;
&lt;br /&gt;
With the previous implementation of this project, students can write comments and request feedback for the comments. There are certain issues with the previous implementation that needs to be addressed.&lt;br /&gt;
&lt;br /&gt;
# The criteria are numbered in the view, and those numbers do not correspond to anything on the rubric form.  So if the rubric is long, it would be quite difficult for the reviewer to figure out what automated feedback referred to which comment.&lt;br /&gt;
# There are too many hardcoded values present in the previously implemented code. We plan to move these hardcoded values to a configuration file and access them when needed.&lt;br /&gt;
# Currently there are many repetitive blocks of code. For Ex.; in _response_analysis.html for the getReviewFeedback(), the API call for each type of tag (sentiment, suggestion, etc) is being repeated. Only the API link differs there.&lt;br /&gt;
#  The previous implementation takes the text area field in the view to fetch the review comment, but it’s not updated dynamically when the user types a comment. The user needs to save the form then go back to edit view and then request feedback.&lt;br /&gt;
&lt;br /&gt;
== Proposed Solution ==&lt;br /&gt;
[[File:PreviousImplementation.jpeg|1000px|thumb| center | previous Implementation]]&lt;br /&gt;
# We need to improve the UI so that if there are many rubric items, users can easily check the feedback for each comment given to each rubric item. We propose the following  solution&lt;br /&gt;
## Each comment on hover shows the user's respective comment on the specific rubric review question so that the feedback is easily accessible.&lt;br /&gt;
### On click of the get review feedback button, we loop through the dynamically created review question form and store the mapping of questions and the reviewer's corresponding comments which on hovered are displayed as a popup.  &lt;br /&gt;
[[File:Proposedsolution.jpeg|1000px|thumb| center | LOFI Design of Proposed Solution]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Another issue with the current implementation is that code is quite repetitive for making different API calls  (Sentiment, Suggestion, etc). We propose to store the API link in the config file and refer to the variable in the getReviewFeedback()&lt;br /&gt;
# We also plan to remove a global variable response_general, which is being used to store the response of API calls. We will refactor the makeRequest function to directly return the response which can be used in various places. This will resolve implicit coupling issues in the code and make it more easily extendable. &lt;br /&gt;
# The previous implementation has hardcoded configuration information like the help text button. We propose to save this information in config files which can be easily modified and will remove unnecessary information from the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation == &lt;br /&gt;
&lt;br /&gt;
=== UI Changes ===&lt;br /&gt;
We refactored the UI of the generated table showing the problem, suggestion, and sentiment of the review comment, by adding a tooltip for prompting the Question and its corresponding review comment in the table itself. &lt;br /&gt;
==== UI screenshots ====&lt;br /&gt;
[[File:Review_table.PNG|500px|thumb|center]]&lt;br /&gt;
[[File:Retry.PNG|400px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - We have added a tooltip in front of every comment number, which on hovering shows the question for which the feedback is given as well as the review comment given for that question.&lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
&lt;br /&gt;
=== Bug Fixes (Dynamic Feedback) ===&lt;br /&gt;
Previously, the implementation took into account the text area field because of which we need to save the form before getting the feedback. We changed the implementation so that users can type in a review comment and dynamically get feedback on it before saving.&lt;br /&gt;
[[File:Bug-fix-1.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - The global variable response_general was used to store the response, which was not needed as the Promise will return the response and we threw an error in case of rejection, which is handled makeRequest method&lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Api refact.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (removing code duplication) ===&lt;br /&gt;
In the previous implementation, code was duplicated for handling different scenarios of fetching the review comment. The code was mostly the same with some conditions. We abstracted the functionality into a method that can be used at multiple places instead of duplicating the code. &lt;br /&gt;
&lt;br /&gt;
Also, the previous implementation was counting the number of rubric questions by parsing the DOM Structure, we refactored that logic as well.&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description  - The internal function create_comment_object is used for generating comment object according to question and class_name of DOM. This comment JSON is then used to pass to the API for fetching the predictions. &lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Create_comment_object.PNG|1200px|thumb|center]]&lt;br /&gt;
[[File:While_loo.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Error handling improvements ===&lt;br /&gt;
We introduced error handling by changing the “Loading…” text to “Request failed. Please try again.” if the API for generating feedback fails. Previously, this  case was not handled&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - We have added try-catch blocks while making API call, and if the promise is rejected we catch the error and change the “Loading…” text at the bottom to “Request failed. Please try again.”&lt;br /&gt;
#Files changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Request_error.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:Request error 2.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (Removing Hardcoded Values) ===&lt;br /&gt;
In the previous implementation the api urls for each analysis and the tool tip description for the analysis were hardcoded into the files. We moved theses values out into the config file below and the values for each of the hardcoded analysis values can be accessed anywhere in the _response_analysis.html.erb file which handles the processing for the analysis. This allows any hardcoded analysis value to be found in one location along with making it easier to append other hardcoded values to each analysis. &lt;br /&gt;
&lt;br /&gt;
[[File:Config File.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (removing duplicate api values) ===&lt;br /&gt;
In the previous implementation each analysis in the _response_analysis.html.erb file had its own block of code for getting the response message, processing values and displaying it to the table. The issue was that many analysis had duplicate blocks of code for getting response message, processing data, and displaying data with only a few analysis requiring different getting, processing, and displaying methods. In the new implementation a for loop would loop through each analysis and would run a default block of code for getting, processing, and displaying data unless the analysis had its own unique getting, processing, and displaying methods where an if statement in the for loop would run the blocks of code for the given method.&lt;br /&gt;
&lt;br /&gt;
[[File:ResponseOld.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:ResponseNew.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Possible files to be edited === &lt;br /&gt;
# review_metrics.yml&lt;br /&gt;
# response.html.erb&lt;br /&gt;
# _response_analysis.html.erb&lt;br /&gt;
# response_controller.rb&lt;br /&gt;
# response_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
== Sample API Input/Output ==&lt;br /&gt;
* Input Text is passed in the following JSON format&lt;br /&gt;
  { &lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot; &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
* Output is returned in the following JSON format:&lt;br /&gt;
  {          &lt;br /&gt;
      &amp;quot;sentiment_score&amp;quot;: 0.9,&lt;br /&gt;
      &amp;quot;sentiment_tone&amp;quot;: &amp;quot;Positive&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions&amp;quot;: &amp;quot;absent&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions_chances&amp;quot;: 10.17,&lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot;,&lt;br /&gt;
      &amp;quot;total_volume&amp;quot;: 10,&lt;br /&gt;
      &amp;quot;volume_without_stopwords&amp;quot;: 6&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
== Testing Plan ==&lt;br /&gt;
&lt;br /&gt;
===Automated Test===&lt;br /&gt;
&lt;br /&gt;
====spec/controllers/response_controller_spec.rb====&lt;br /&gt;
&lt;br /&gt;
Added a test that confirms the correct API URLS are being pulled from the config file.&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2021-11-29 at 10.43.16 AM.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Manual Test===&lt;br /&gt;
&lt;br /&gt;
#The functionality was written on the client side in javascript solely in _response_analysis.html.erb&lt;br /&gt;
#To test this view, any type of review must be accessible as a student.&lt;br /&gt;
#There is a button at the bottom of the review called 'Get Review Feedback'.&lt;br /&gt;
#When pressing button, API calls are issued and the metrics will show up within the table (a sample of which is shown in above screenshot).&lt;br /&gt;
#As API calls will take time, 'Loading..' text will appear until the API calls are complete&lt;br /&gt;
#All the review feedback for the comments will be displayed in a colorful table.&lt;br /&gt;
#In the feedback table, upon hovering on the comment number, we will be able to see the rubric item and review comments associated with that particular rubric item&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
# https://docs.google.com/document/d/1slx4HPIbgTH-psIKMSCF-HDF9brxf-FuYhzVT9ZiIrM/edit#heading=h.fxfungdw1d5r&lt;br /&gt;
# https://github.com/expertiza/expertiza/pull/2159&lt;br /&gt;
# https://youtu.be/oN7qCNTFBE8&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Prashan Sengo (psengo)&lt;br /&gt;
&lt;br /&gt;
* Griffin Brookshire (glbrook2)&lt;br /&gt;
&lt;br /&gt;
* Divyang Doshi (ddoshi2)&lt;br /&gt;
&lt;br /&gt;
* Srujan Ponnur (sponnur)&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=141847</id>
		<title>CSC/ECE 517 Fall 2021 - E2150. Integrate suggestion detection algorithm</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=141847"/>
		<updated>2021-11-29T15:46:40Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem Definition ==&lt;br /&gt;
Peer-review systems like Expertiza utilize a lot of students’ input to determine each other’s performance. At the same time, students learn from the reviews they receive to improve their own performance. In order to make this happen, it would be good to have everyone give quality reviews instead of generic ones. Currently, Expertiza has a few classifiers that can detect useful features of review comments, such as whether they contain suggestions. The suggestion-detection algorithm has been coded as a web service, and other detection algorithms, such as problem detection and sentiment analysis, also exist as newer web services. We need to make the UI more intuitive by allowing users to view the feedback of specific review comments and the code needs to be refactored to remove redundancy to follow the DRY principle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Previous Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The previous implementation added the following features:&lt;br /&gt;
# Setup a config file 'review_metric.yml' where the instructor can select what review metric to display for the current assignments&lt;br /&gt;
# API calls (sentiment, problem, suggestion) are made and a table is rendered below, displaying the feedback of the review comments.&lt;br /&gt;
# The total time taken by the API calls was also displayed.&lt;br /&gt;
&lt;br /&gt;
=== UI Screenshots ===&lt;br /&gt;
The following image shows how a reviewer interacts with the system to get feedback on the review comments.&lt;br /&gt;
[[File:Steps_metric.png|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Control Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Review_metric.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Issues with Previous Work ==&lt;br /&gt;
&lt;br /&gt;
With the previous implementation of this project, students can write comments and request feedback for the comments. There are certain issues with the previous implementation that needs to be addressed.&lt;br /&gt;
&lt;br /&gt;
# The criteria are numbered in the view, and those numbers do not correspond to anything on the rubric form.  So if the rubric is long, it would be quite difficult for the reviewer to figure out what automated feedback referred to which comment.&lt;br /&gt;
# There are too many hardcoded values present in the previously implemented code. We plan to move these hardcoded values to a configuration file and access them when needed.&lt;br /&gt;
# Currently there are many repetitive blocks of code. For Ex.; in _response_analysis.html for the getReviewFeedback(), the API call for each type of tag (sentiment, suggestion, etc) is being repeated. Only the API link differs there.&lt;br /&gt;
#  The previous implementation takes the text area field in the view to fetch the review comment, but it’s not updated dynamically when the user types a comment. The user needs to save the form then go back to edit view and then request feedback.&lt;br /&gt;
&lt;br /&gt;
== Proposed Solution ==&lt;br /&gt;
[[File:PreviousImplementation.jpeg|1000px|thumb| center | previous Implementation]]&lt;br /&gt;
# We need to improve the UI so that if there are many rubric items, users can easily check the feedback for each comment given to each rubric item. We propose the following  solution&lt;br /&gt;
## Each comment on hover shows the user's respective comment on the specific rubric review question so that the feedback is easily accessible.&lt;br /&gt;
### On click of the get review feedback button, we loop through the dynamically created review question form and store the mapping of questions and the reviewer's corresponding comments which on hovered are displayed as a popup.  &lt;br /&gt;
[[File:Proposedsolution.jpeg|1000px|thumb| center | LOFI Design of Proposed Solution]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Another issue with the current implementation is that code is quite repetitive for making different API calls  (Sentiment, Suggestion, etc). We propose to store the API link in the config file and refer to the variable in the getReviewFeedback()&lt;br /&gt;
# We also plan to remove a global variable response_general, which is being used to store the response of API calls. We will refactor the makeRequest function to directly return the response which can be used in various places. This will resolve implicit coupling issues in the code and make it more easily extendable. &lt;br /&gt;
# The previous implementation has hardcoded configuration information like the help text button. We propose to save this information in config files which can be easily modified and will remove unnecessary information from the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation == &lt;br /&gt;
&lt;br /&gt;
=== UI Changes ===&lt;br /&gt;
We refactored the UI of the generated table showing the problem, suggestion, and sentiment of the review comment, by adding a tooltip for prompting the Question and its corresponding review comment in the table itself. &lt;br /&gt;
==== UI screenshots ====&lt;br /&gt;
[[File:Review_table.PNG|500px|thumb|center]]&lt;br /&gt;
[[File:Retry.PNG|400px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - We have added a tooltip in front of every comment number, which on hovering shows the question for which the feedback is given as well as the review comment given for that question.&lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
&lt;br /&gt;
=== Bug Fixes (Dynamic Feedback) ===&lt;br /&gt;
Previously, the implementation took into account the text area field because of which we need to save the form before getting the feedback. We changed the implementation so that users can type in a review comment and dynamically get feedback on it before saving.&lt;br /&gt;
[[File:Bug-fix-1.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - The global variable response_general was used to store the response, which was not needed as the Promise will return the response and we threw an error in case of rejection, which is handled makeRequest method&lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Api refact.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (removing code duplication) ===&lt;br /&gt;
In the previous implementation, code was duplicated for handling different scenarios of fetching the review comment. The code was mostly the same with some conditions. We abstracted the functionality into a method that can be used at multiple places instead of duplicating the code. &lt;br /&gt;
&lt;br /&gt;
Also, the previous implementation was counting the number of rubric questions by parsing the DOM Structure, we refactored that logic as well.&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description  - The internal function create_comment_object is used for generating comment object according to question and class_name of DOM. This comment JSON is then used to pass to the API for fetching the predictions. &lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Create_comment_object.PNG|1200px|thumb|center]]&lt;br /&gt;
[[File:While_loo.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Error handling improvements ===&lt;br /&gt;
We introduced error handling by changing the “Loading…” text to “Request failed. Please try again.” if the API for generating feedback fails. Previously, this  case was not handled&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - We have added try-catch blocks while making API call, and if the promise is rejected we catch the error and change the “Loading…” text at the bottom to “Request failed. Please try again.”&lt;br /&gt;
#Files changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Request_error.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:Request error 2.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (Removing Hardcoded Values) ===&lt;br /&gt;
In the previous implementation the api urls for each analysis and the tool tip description for the analysis were hardcoded into the files. We moved theses values out into the config file below and the values for each of the hardcoded analysis values can be accessed anywhere in the _response_analysis.html.erb file which handles the processing for the analysis. This allows any hardcoded analysis value to be found in one location along with making it easier to append other hardcoded values to each analysis. &lt;br /&gt;
&lt;br /&gt;
[[File:Config File.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (removing duplicate api values) ===&lt;br /&gt;
In the previous implementation each analysis in the _response_analysis.html.erb file had its own block of code for getting the response message, processing values and displaying it to the table. The issue was that many analysis had duplicate blocks of code for getting response message, processing data, and displaying data with only a few analysis requiring different getting, processing, and displaying methods. In the new implementation a for loop would loop through each analysis and would run a default block of code for getting, processing, and displaying data unless the analysis had its own unique getting, processing, and displaying methods where an if statement in the for loop would run the blocks of code for the given method.&lt;br /&gt;
&lt;br /&gt;
[[File:ResponseOld.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:ResponseNew.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Possible files to be edited === &lt;br /&gt;
# review_metrics.yml&lt;br /&gt;
# response.html.erb&lt;br /&gt;
# _response_analysis.html.erb&lt;br /&gt;
# response_controller.rb&lt;br /&gt;
# response_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
== Sample API Input/Output ==&lt;br /&gt;
* Input Text is passed in the following JSON format&lt;br /&gt;
  { &lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot; &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
* Output is returned in the following JSON format:&lt;br /&gt;
  {          &lt;br /&gt;
      &amp;quot;sentiment_score&amp;quot;: 0.9,&lt;br /&gt;
      &amp;quot;sentiment_tone&amp;quot;: &amp;quot;Positive&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions&amp;quot;: &amp;quot;absent&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions_chances&amp;quot;: 10.17,&lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot;,&lt;br /&gt;
      &amp;quot;total_volume&amp;quot;: 10,&lt;br /&gt;
      &amp;quot;volume_without_stopwords&amp;quot;: 6&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
== Testing Plan ==&lt;br /&gt;
&lt;br /&gt;
===Automated Test===&lt;br /&gt;
&lt;br /&gt;
====spec/controllers/response_controller_spec.rb====&lt;br /&gt;
&lt;br /&gt;
Added a test that confirms the correct API URLS are being pulled from the config file.&lt;br /&gt;
&lt;br /&gt;
[[File:Screen Shot 2021-11-29 at 10.43.16 AM.png|600px]]&lt;br /&gt;
&lt;br /&gt;
===Manual Test===&lt;br /&gt;
&lt;br /&gt;
#The functionality was written on the client side in javascript solely in _response_analysis.html.erb&lt;br /&gt;
#To test this view, any type of review must be accessible as a student.&lt;br /&gt;
#There is a button at the bottom of the review called 'Get Review Feedback'.&lt;br /&gt;
#When pressing button, API calls are issued and the metrics will show up within the table (a sample of which is shown in above screenshot).&lt;br /&gt;
#As API calls will take time, 'Loading..' text will appear until the API calls are complete&lt;br /&gt;
#All the review feedback for the comments will be displayed in a colorful table.&lt;br /&gt;
#In the feedback table, upon hovering on the comment number, we will be able to see the rubric item and review comments associated with that particular rubric item&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
# https://docs.google.com/document/d/1slx4HPIbgTH-psIKMSCF-HDF9brxf-FuYhzVT9ZiIrM/edit#heading=h.fxfungdw1d5r&lt;br /&gt;
# https://github.com/expertiza/expertiza/pull/1952 (Previous implementation pull request)&lt;br /&gt;
# https://youtu.be/oN7qCNTFBE8&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Prashan Sengo (psengo)&lt;br /&gt;
&lt;br /&gt;
* Griffin Brookshire (glbrook2)&lt;br /&gt;
&lt;br /&gt;
* Divyang Doshi (ddoshi2)&lt;br /&gt;
&lt;br /&gt;
* Srujan Ponnur (sponnur)&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2021-11-29_at_10.43.16_AM.png&amp;diff=141846</id>
		<title>File:Screen Shot 2021-11-29 at 10.43.16 AM.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Screen_Shot_2021-11-29_at_10.43.16_AM.png&amp;diff=141846"/>
		<updated>2021-11-29T15:44:26Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: test code&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;test code&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=141845</id>
		<title>CSC/ECE 517 Fall 2021 - E2150. Integrate suggestion detection algorithm</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=141845"/>
		<updated>2021-11-29T15:36:39Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issues with Previous Work */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem Definition ==&lt;br /&gt;
Peer-review systems like Expertiza utilize a lot of students’ input to determine each other’s performance. At the same time, students learn from the reviews they receive to improve their own performance. In order to make this happen, it would be good to have everyone give quality reviews instead of generic ones. Currently, Expertiza has a few classifiers that can detect useful features of review comments, such as whether they contain suggestions. The suggestion-detection algorithm has been coded as a web service, and other detection algorithms, such as problem detection and sentiment analysis, also exist as newer web services. We need to make the UI more intuitive by allowing users to view the feedback of specific review comments and the code needs to be refactored to remove redundancy to follow the DRY principle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Previous Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The previous implementation added the following features:&lt;br /&gt;
# Setup a config file 'review_metric.yml' where the instructor can select what review metric to display for the current assignments&lt;br /&gt;
# API calls (sentiment, problem, suggestion) are made and a table is rendered below, displaying the feedback of the review comments.&lt;br /&gt;
# The total time taken by the API calls was also displayed.&lt;br /&gt;
&lt;br /&gt;
=== UI Screenshots ===&lt;br /&gt;
The following image shows how a reviewer interacts with the system to get feedback on the review comments.&lt;br /&gt;
[[File:Steps_metric.png|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Control Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Review_metric.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Issues with Previous Work ==&lt;br /&gt;
&lt;br /&gt;
With the previous implementation of this project, students can write comments and request feedback for the comments. There are certain issues with the previous implementation that needs to be addressed.&lt;br /&gt;
&lt;br /&gt;
# The criteria are numbered in the view, and those numbers do not correspond to anything on the rubric form.  So if the rubric is long, it would be quite difficult for the reviewer to figure out what automated feedback referred to which comment.&lt;br /&gt;
# There are too many hardcoded values present in the previously implemented code. We plan to move these hardcoded values to a configuration file and access them when needed.&lt;br /&gt;
# Currently there are many repetitive blocks of code. For Ex.; in _response_analysis.html for the getReviewFeedback(), the API call for each type of tag (sentiment, suggestion, etc) is being repeated. Only the API link differs there.&lt;br /&gt;
#  The previous implementation takes the text area field in the view to fetch the review comment, but it’s not updated dynamically when the user types a comment. The user needs to save the form then go back to edit view and then request feedback.&lt;br /&gt;
&lt;br /&gt;
== Proposed Solution ==&lt;br /&gt;
[[File:PreviousImplementation.jpeg|1000px|thumb| center | previous Implementation]]&lt;br /&gt;
# We need to improve the UI so that if there are many rubric items, users can easily check the feedback for each comment given to each rubric item. We propose the following  solution&lt;br /&gt;
## Each comment on hover shows the user's respective comment on the specific rubric review question so that the feedback is easily accessible.&lt;br /&gt;
### On click of the get review feedback button, we loop through the dynamically created review question form and store the mapping of questions and the reviewer's corresponding comments which on hovered are displayed as a popup.  &lt;br /&gt;
[[File:Proposedsolution.jpeg|1000px|thumb| center | LOFI Design of Proposed Solution]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Another issue with the current implementation is that code is quite repetitive for making different API calls  (Sentiment, Suggestion, etc). We propose to store the API link in the config file and refer to the variable in the getReviewFeedback()&lt;br /&gt;
# We also plan to remove a global variable response_general, which is being used to store the response of API calls. We will refactor the makeRequest function to directly return the response which can be used in various places. This will resolve implicit coupling issues in the code and make it more easily extendable. &lt;br /&gt;
# The previous implementation has hardcoded configuration information like the help text button. We propose to save this information in config files which can be easily modified and will remove unnecessary information from the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Implementation == &lt;br /&gt;
&lt;br /&gt;
=== UI Changes ===&lt;br /&gt;
We refactored the UI of the generated table showing the problem, suggestion, and sentiment of the review comment, by adding a tooltip for prompting the Question and its corresponding review comment in the table itself. &lt;br /&gt;
==== UI screenshots ====&lt;br /&gt;
[[File:Review_table.PNG|500px|thumb|center]]&lt;br /&gt;
[[File:Retry.PNG|400px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - We have added a tooltip in front of every comment number, which on hovering shows the question for which the feedback is given as well as the review comment given for that question.&lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
&lt;br /&gt;
=== Bug Fixes (Dynamic Feedback) ===&lt;br /&gt;
Previously, the implementation took into account the text area field because of which we need to save the form before getting the feedback. We changed the implementation so that users can type in a review comment and dynamically get feedback on it before saving.&lt;br /&gt;
[[File:Bug-fix-1.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - The global variable response_general was used to store the response, which was not needed as the Promise will return the response and we threw an error in case of rejection, which is handled makeRequest method&lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Api refact.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (removing code duplication) ===&lt;br /&gt;
In the previous implementation, code was duplicated for handling different scenarios of fetching the review comment. The code was mostly the same with some conditions. We abstracted the functionality into a method that can be used at multiple places instead of duplicating the code. &lt;br /&gt;
&lt;br /&gt;
Also, the previous implementation was counting the number of rubric questions by parsing the DOM Structure, we refactored that logic as well.&lt;br /&gt;
&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description  - The internal function create_comment_object is used for generating comment object according to question and class_name of DOM. This comment JSON is then used to pass to the API for fetching the predictions. &lt;br /&gt;
#File changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Create_comment_object.PNG|1200px|thumb|center]]&lt;br /&gt;
[[File:While_loo.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Error handling improvements ===&lt;br /&gt;
We introduced error handling by changing the “Loading…” text to “Request failed. Please try again.” if the API for generating feedback fails. Previously, this  case was not handled&lt;br /&gt;
==== Javascript implementation ====&lt;br /&gt;
#Description - We have added try-catch blocks while making API call, and if the promise is rejected we catch the error and change the “Loading…” text at the bottom to “Request failed. Please try again.”&lt;br /&gt;
#Files changed - app/views/response/_response_analysis.html.erb&lt;br /&gt;
[[File:Request_error.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:Request error 2.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (Removing Hardcoded Values) ===&lt;br /&gt;
In the previous implementation the api urls for each analysis and the tool tip description for the analysis were hardcoded into the files. We moved theses values out into the config file below and the values for each of the hardcoded analysis values can be accessed anywhere in the _response_analysis.html.erb file which handles the processing for the analysis. This allows any hardcoded analysis value to be found in one location along with making it easier to append other hardcoded values to each analysis. &lt;br /&gt;
&lt;br /&gt;
[[File:Config File.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Refactoring (removing duplicate api values) ===&lt;br /&gt;
In the previous implementation each analysis in the _response_analysis.html.erb file had its own block of code for getting the response message, processing values and displaying it to the table. The issue was that many analysis had duplicate blocks of code for getting response message, processing data, and displaying data with only a few analysis requiring different getting, processing, and displaying methods. In the new implementation a for loop would loop through each analysis and would run a default block of code for getting, processing, and displaying data unless the analysis had its own unique getting, processing, and displaying methods where an if statement in the for loop would run the blocks of code for the given method.&lt;br /&gt;
&lt;br /&gt;
[[File:ResponseOld.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:ResponseNew.PNG|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Possible files to be edited === &lt;br /&gt;
# review_metrics.yml&lt;br /&gt;
# response.html.erb&lt;br /&gt;
# _response_analysis.html.erb&lt;br /&gt;
# response_controller.rb&lt;br /&gt;
# response_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
== Sample API Input/Output ==&lt;br /&gt;
* Input Text is passed in the following JSON format&lt;br /&gt;
  { &lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot; &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
* Output is returned in the following JSON format:&lt;br /&gt;
  {          &lt;br /&gt;
      &amp;quot;sentiment_score&amp;quot;: 0.9,&lt;br /&gt;
      &amp;quot;sentiment_tone&amp;quot;: &amp;quot;Positive&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions&amp;quot;: &amp;quot;absent&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions_chances&amp;quot;: 10.17,&lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot;,&lt;br /&gt;
      &amp;quot;total_volume&amp;quot;: 10,&lt;br /&gt;
      &amp;quot;volume_without_stopwords&amp;quot;: 6&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
== Testing Plan ==&lt;br /&gt;
This project mainly addresses the UI issues and some code refactoring in views. Therefore, we will be focussing on view tests as all the automated tests have been previously implemented and new code won't affect those.&lt;br /&gt;
&lt;br /&gt;
===View Tests(Manual)===&lt;br /&gt;
&lt;br /&gt;
#The functionality was written on the client side in javascript solely in _response_analysis.html.erb&lt;br /&gt;
#To test this view, any type of review must be accessible as a student.&lt;br /&gt;
#There is a button at the bottom of the review called 'Get Review Feedback'.&lt;br /&gt;
#When pressing button, API calls are issued and the metrics will show up within the table (a sample of which is shown in above screenshot).&lt;br /&gt;
#As API calls will take time, 'Loading..' text will appear until the API calls are complete&lt;br /&gt;
#All the review feedback for the comments will be displayed in a colorful table.&lt;br /&gt;
#In the feedback table, upon hovering on the comment number, we will be able to see the rubric item and review comments associated with that particular rubric item&lt;br /&gt;
&lt;br /&gt;
== Important Links ==&lt;br /&gt;
# https://docs.google.com/document/d/1slx4HPIbgTH-psIKMSCF-HDF9brxf-FuYhzVT9ZiIrM/edit#heading=h.fxfungdw1d5r&lt;br /&gt;
# https://github.com/expertiza/expertiza/pull/1952 (Previous implementation pull request)&lt;br /&gt;
# https://youtu.be/oN7qCNTFBE8&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Prashan Sengo (psengo)&lt;br /&gt;
&lt;br /&gt;
* Griffin Brookshire (glbrook2)&lt;br /&gt;
&lt;br /&gt;
* Divyang Doshi (ddoshi2)&lt;br /&gt;
&lt;br /&gt;
* Srujan Ponnur (sponnur)&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=140500</id>
		<title>CSC/ECE 517 Fall 2021 - E2150. Integrate suggestion detection algorithm</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2150._Integrate_suggestion_detection_algorithm&amp;diff=140500"/>
		<updated>2021-11-03T01:04:14Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Team */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem Definition ==&lt;br /&gt;
Peer-review systems like Expertiza utilize a lot of students’ input to determine each other’s performance. At the same time, students learn from the reviews they receive to improve their own performance. In order to make this happen, it would be good to have everyone give quality reviews instead of generic ones. Currently, Expertiza has a few classifiers that can detect useful features of review comments, such as whether they contain suggestions. The suggestion-detection algorithm has been coded as a web service, and other detection algorithms, such as problem detection and sentiment analysis, also exist as newer web services. We need to make the UI more intuitive by allowing users to view the feedback of specific review comments and the code needs to be refactored to remove redundancy to follow the DRY principle.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Previous Implementation ==&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The previous implementation added the following features:&lt;br /&gt;
# Setup a config file 'review_metric.yml' where the instructor can select what review metric to display for the current assignments&lt;br /&gt;
# API calls (sentiment, problem, suggestion) are made and a table is rendered below, displaying the feedback of the review comments.&lt;br /&gt;
# The total time taken by the API calls was also displayed.&lt;br /&gt;
&lt;br /&gt;
=== UI Screenshots ===&lt;br /&gt;
The following image shows how a reviewer interacts with the system to get feedback on the review comments.&lt;br /&gt;
[[File:Steps_metric.png|1200px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=== Control Flow ===&lt;br /&gt;
&lt;br /&gt;
[[File:Review_metric.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Issues with Previous Work ==&lt;br /&gt;
&lt;br /&gt;
With the previous implementation of this project, students can write comments and request feedback for the comments. There are certain issues with the previous implementation that needs to be addressed.&lt;br /&gt;
&lt;br /&gt;
# The criteria are numbered in the view, and those numbers do not correspond to anything on the rubric form.  So if the rubric is long, it would be quite difficult for the reviewer to figure out what automated feedback referred to which comment.&lt;br /&gt;
# Too much specific information on metrics is encoded into the text.  While some of the info is in configuration files, the help text for the info buttons is in the code.&lt;br /&gt;
# Currently there are many repetitive blocks of code. For Ex.; in _response_analysis.html for the getReviewFeedback(), the API call for each type of tag (sentiment, suggestion, etc) is being repeated. Only the API link differs there.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed Solution == &lt;br /&gt;
===  Refactoring ===&lt;br /&gt;
# We need to improve the UI so that if there are many rubric items, user can easily check the feedback for each comment given to each rubric item. We propose that instead of showing a table with feedback on all comments, we will be showing the feedback below each rubric item so that the feedback is easily accessible.&lt;br /&gt;
# Another issue with the current implementation is that code is quite repetitive for making different API calls  (Sentiment, Suggestion, etc). We propose to store the API link in the config file and use the variable in the getReviewFeedback()&lt;br /&gt;
# We also plan to remove a global variable response_general, which is being used to store the response of API call. We will refactor the makeRequest function to directly return the response which can be used in various places. This will resolve implicit coupling issues in the code and make it more easily extendible. &lt;br /&gt;
# The previous implementation has hardcoded configuration information like the help text button. We propose to save this information in config files which can be easily modified and will remove unnecessary information from the code.&lt;br /&gt;
&lt;br /&gt;
=== Possible files to be edited === &lt;br /&gt;
# review_metrics.yml&lt;br /&gt;
# response.html.erb&lt;br /&gt;
# _response_analysis.html.erb&lt;br /&gt;
# response_controller.rb&lt;br /&gt;
# response_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
== Sample API Input/Output ==&lt;br /&gt;
* Input Text is passed in the following JSON format&lt;br /&gt;
  { &lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot; &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
* Output is returned in the following JSON format:&lt;br /&gt;
  {          &lt;br /&gt;
      &amp;quot;sentiment_score&amp;quot;: 0.9,&lt;br /&gt;
      &amp;quot;sentiment_tone&amp;quot;: &amp;quot;Positive&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions&amp;quot;: &amp;quot;absent&amp;quot;,&lt;br /&gt;
      &amp;quot;suggestions_chances&amp;quot;: 10.17,&lt;br /&gt;
      &amp;quot;text&amp;quot;: &amp;quot;This is an excellent project. Keep up the great work&amp;quot;,&lt;br /&gt;
      &amp;quot;total_volume&amp;quot;: 10,&lt;br /&gt;
      &amp;quot;volume_without_stopwords&amp;quot;: 6&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
* Prashan Sengo (psengo)&lt;br /&gt;
&lt;br /&gt;
* Griffin Brookshire (glbrook2)&lt;br /&gt;
&lt;br /&gt;
* Divyang Doshi (ddoshi2)&lt;br /&gt;
&lt;br /&gt;
* Srujan (sponnur)&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140231</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140231"/>
		<updated>2021-10-27T03:53:08Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
The implementation and testing for this issue already existed in the beta branch, which will be discussed below.&amp;lt;br&amp;gt;&lt;br /&gt;
This behavior was already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality was also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manual Testing Results'''&lt;br /&gt;
&lt;br /&gt;
After following the step-by-step instructions for Issue1 in the Test Plan below, the following email was received. This shows that when a new user was imported through the assignment participants page, they received a welcome email.&lt;br /&gt;
&lt;br /&gt;
[[File:Welcome email.png|750px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 1'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Navigate to Manage --&amp;gt; Assignment page.&lt;br /&gt;
&lt;br /&gt;
Step 2: Click on add participants for any of the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Click &amp;quot;Import course participants&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Step 4: Choose a csv file to be imported (follow the format given on the website).&lt;br /&gt;
&lt;br /&gt;
Step 5: The users mentioned in the csv file and don't exist on Expertiza should get a new user email.&lt;br /&gt;
&lt;br /&gt;
'''Issue 2'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Add an existing user to the new assignment&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates for the new assignment.&lt;br /&gt;
&lt;br /&gt;
Step 4: Set the due date to 1 hour and 5 seconds from now.&lt;br /&gt;
&lt;br /&gt;
Step 5: The user should recieve a reminder email with the relevant links to the assignment.&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140229</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140229"/>
		<updated>2021-10-27T03:51:51Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
The implementation and testing for this issue already existed in the beta branch, which will be discussed below.&amp;lt;br&amp;gt;&lt;br /&gt;
This behavior was already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality was also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Manual Testing Results'''&lt;br /&gt;
&lt;br /&gt;
After following the step-by-step instructions for Issue1 in the Test Plan below, the following email was received. This shows that when a new user was imported through the assignment participants page, they received a welcome email.&lt;br /&gt;
&lt;br /&gt;
[[File:Welcome email.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 1'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Navigate to Manage --&amp;gt; Assignment page.&lt;br /&gt;
&lt;br /&gt;
Step 2: Click on add participants for any of the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Click &amp;quot;Import course participants&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Step 4: Choose a csv file to be imported (follow the format given on the website).&lt;br /&gt;
&lt;br /&gt;
Step 5: The users mentioned in the csv file and don't exist on Expertiza should get a new user email.&lt;br /&gt;
&lt;br /&gt;
'''Issue 2'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Add an existing user to the new assignment&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates for the new assignment.&lt;br /&gt;
&lt;br /&gt;
Step 4: Set the due date to 1 hour and 5 seconds from now.&lt;br /&gt;
&lt;br /&gt;
Step 5: The user should recieve a reminder email with the relevant links to the assignment.&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Welcome_email.png&amp;diff=140228</id>
		<title>File:Welcome email.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Welcome_email.png&amp;diff=140228"/>
		<updated>2021-10-27T03:48:18Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: Screenshot of email received after importing a new student via csv&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Screenshot of email received after importing a new student via csv&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140225</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140225"/>
		<updated>2021-10-27T03:46:35Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
The implementation and testing for this issue already existed in the beta branch, which will be discussed below.&amp;lt;br&amp;gt;&lt;br /&gt;
This behavior was already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality was also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Manual Testing Results&lt;br /&gt;
&lt;br /&gt;
[[File:Example.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 1'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Navigate to Manage --&amp;gt; Assignment page.&lt;br /&gt;
&lt;br /&gt;
Step 2: Click on add participants for any of the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Click &amp;quot;Import course participants&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Step 4: Choose a csv file to be imported (follow the format given on the website).&lt;br /&gt;
&lt;br /&gt;
Step 5: The users mentioned in the csv file and don't exist on Expertiza should get a new user email.&lt;br /&gt;
&lt;br /&gt;
'''Issue 2'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Add an existing user to the new assignment&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates for the new assignment.&lt;br /&gt;
&lt;br /&gt;
Step 4: Set the due date to 1 hour and 5 seconds from now.&lt;br /&gt;
&lt;br /&gt;
Step 5: The user should recieve a reminder email with the relevant links to the assignment.&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140117</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=140117"/>
		<updated>2021-10-26T23:14:00Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
The implementation and testing for this issue already existed in the beta branch, which will be discussed below.&amp;lt;br&amp;gt;&lt;br /&gt;
This behavior was already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality was also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 1'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Navigate to Manage --&amp;gt; Assignment page.&lt;br /&gt;
&lt;br /&gt;
Step 2: Click on add participants for any of the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Click &amp;quot;Import course participants&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Step 4: Choose a csv file to be imported (follow the format given on the website).&lt;br /&gt;
&lt;br /&gt;
Step 5: The users mentioned in the csv file and don't exist on Expertiza should get a new user email.&lt;br /&gt;
&lt;br /&gt;
'''Issue 2'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Add an existing user to the new assignment&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates for the new assignment.&lt;br /&gt;
&lt;br /&gt;
Step 4: Set the due date to 1 hour and 5 seconds from now.&lt;br /&gt;
&lt;br /&gt;
Step 5: The user should recieve a reminder email with the relevant links to the assignment.&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139848</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139848"/>
		<updated>2021-10-21T03:52:22Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
The implementation and testing for this issue already existed in the beta branch, which will be discussed below.&amp;lt;br&amp;gt;&lt;br /&gt;
This behavior was already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality was also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 1'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Navigate to Manage --&amp;gt; Assignment page.&lt;br /&gt;
&lt;br /&gt;
Step 2: Click on add participants for any of the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Click &amp;quot;Import course participants&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Step 4: Choose a csv file to be imported (follow the format given on the website).&lt;br /&gt;
&lt;br /&gt;
Step 5: The users mentioned in the csv file and don't exist on Expertiza should get a new user email.&lt;br /&gt;
&lt;br /&gt;
Step 6: To check e-mail is received or not, log in with following credentials: username [ 'expertiza.development@gmail.com' ] password [ 'qwer@1234' ].&lt;br /&gt;
&lt;br /&gt;
'''Issue 2'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Add an existing user to the new assignment&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates for the new assignment.&lt;br /&gt;
&lt;br /&gt;
Step 4: Set the due date to 1 hour and 5 seconds from now.&lt;br /&gt;
&lt;br /&gt;
Step 5: To check e-mail is received or not, log in with following credentials: username [ 'expertiza.development@gmail.com' ] password [ 'qwer@1234' ].&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139841</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139841"/>
		<updated>2021-10-21T03:40:17Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 1'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Navigate to Manage --&amp;gt; Assignment page.&lt;br /&gt;
&lt;br /&gt;
Step 2: Click on add participants for any of the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Click &amp;quot;Import course participants&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Step 4: Choose a csv file to be imported (follow the format given on the website).&lt;br /&gt;
&lt;br /&gt;
Step 5: The users mentioned in the csv file and don't exist on Expertiza should get a new user email.&lt;br /&gt;
&lt;br /&gt;
Step 6: To check e-mail is received or not, log in with following credentials: username [ 'expertiza.development@gmail.com' ] password [ 'qwer@1234' ].&lt;br /&gt;
&lt;br /&gt;
'''Issue 2'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Add an existing user to the new assignment&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates for the new assignment.&lt;br /&gt;
&lt;br /&gt;
Step 4: Set the due date to 1 hour and 5 seconds from now.&lt;br /&gt;
&lt;br /&gt;
Step 5: To check e-mail is received or not, log in with following credentials: username [ 'expertiza.development@gmail.com' ] password [ 'qwer@1234' ].&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139839</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139839"/>
		<updated>2021-10-21T03:38:49Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 1'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Navigate to Manage --&amp;gt; Assignment page.&lt;br /&gt;
&lt;br /&gt;
Step 2: Click on add participants for any of the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Click &amp;quot;Import course participants&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Step 4: Choose a csv file to be imported (follow the format given on the website).&lt;br /&gt;
&lt;br /&gt;
Step 5: The users mentioned in the csv file and don't exist on Expertiza should get a new user email.&lt;br /&gt;
&lt;br /&gt;
Step 6: To check e-mail is received or not, log in with following credentials: username [ 'expertiza.development@gmail.com' ] password [ 'qwer@1234' ].&lt;br /&gt;
&lt;br /&gt;
'''Issue 2'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Add an existing user to the new assignment&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates for the new assignment.&lt;br /&gt;
&lt;br /&gt;
Step 4: Set the due date to 1 hour and 5 seconds from now.&lt;br /&gt;
&lt;br /&gt;
Step 5: Sign into the participants account and check for email.&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139822</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139822"/>
		<updated>2021-10-21T03:30:02Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Issue 2''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Issue 3'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139817</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139817"/>
		<updated>2021-10-21T03:26:45Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139813</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139813"/>
		<updated>2021-10-21T03:22:08Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue3 (111) - Adding relevant links to reminder emails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139811</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139811"/>
		<updated>2021-10-21T03:21:40Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue3 (111) - Adding relevant links to reminder emails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\n&amp;lt;br&amp;gt;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\n&amp;lt;br&amp;gt;Deadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139806</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139806"/>
		<updated>2021-10-21T03:14:58Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue3 (111) - Adding relevant links to reminder emails */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First we get the user associated with the email, then we get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139805</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139805"/>
		<updated>2021-10-21T03:13:39Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
We implemented this behavior by enhancing the 'email_reminder' function within the app/mailers/mail_worker.rb file. First I added a line that gets the user associated with the email. Then I get the participant object associated with the particular user and the assignment. The ID of this object is the query parameter located at the end of the relevant link.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''mail_worker.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def email_reminder(emails, deadline_type)&lt;br /&gt;
  assignment = Assignment.find(self.assignment_id)&lt;br /&gt;
  subject = &amp;quot;Message regarding #{deadline_type} for assignment #{assignment.name}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Defining the body of mail&lt;br /&gt;
  body = &amp;quot;This is a reminder to complete #{deadline_type} for assignment #{assignment.name}.\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  emails.each do |mail|&lt;br /&gt;
    # Since the email is not unique fetching the first instance in results returned when searching via email&lt;br /&gt;
    user = User.where(email: mail).first&lt;br /&gt;
&lt;br /&gt;
    # Finding the mapping between participant and assignment so that it can be sent as a query param&lt;br /&gt;
    participant_assignment_id = Participant.find(user_id: user.id.to_s, parent_id: self.assignment_id.to_s).first.id&lt;br /&gt;
&lt;br /&gt;
    # This is the link which User can use to navigate&lt;br /&gt;
    link_to_destination = &amp;quot;Please follow the link: http://expertiza.ncsu.edu/student_task/view?id=#{participant_assignment_id}\n&amp;quot;&lt;br /&gt;
    body += link_to_destination + &amp;quot;Deadline is #{self.due_at}. If you have already done the #{deadline_type}, then please ignore this mail.&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    # Send mail to the user&lt;br /&gt;
    @mail = Mailer.delayed_message(bcc: mail, subject: subject, body: body)&lt;br /&gt;
    @mail.deliver_now&lt;br /&gt;
    Rails.logger.info mail&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This function is clearly tested through a new test we added to the spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''sidekiq_mail_worker_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
it &amp;quot;should send reminder email to required email address with proper content&amp;quot; do&lt;br /&gt;
  Sidekiq::Testing.inline!&lt;br /&gt;
  ActionMailer::Base.deliveries.clear&lt;br /&gt;
  worker = MailWorker.new&lt;br /&gt;
  worker.perform(&amp;quot;1&amp;quot;, &amp;quot;metareview&amp;quot;, &amp;quot;2018-12-31 00:00:01&amp;quot;)&lt;br /&gt;
  expect(ActionMailer::Base.deliveries.size).to eq(1)&lt;br /&gt;
  email = ActionMailer::Base.deliveries.first&lt;br /&gt;
  expect(email.from[0]).to eq(&amp;quot;expertiza.development@gmail.com&amp;quot;)&lt;br /&gt;
  expect(email.bcc[0]).to eq(&amp;quot;psingh22@ncsu.edu&amp;quot;)&lt;br /&gt;
  expect(email.subject).to eq(&amp;quot;Message regarding teammate review for assignment no assignment&amp;quot;)&lt;br /&gt;
  expect(email.body).to eq(&amp;quot;This is a reminder to complete teammate review for assignment no assignment.\nPlease follow the link: http://expertiza.ncsu.edu/student_task/view?id=1\nDeadline is 2018-12-31 00:00:01. If you have already done the teammate review, then please ignore this mail.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139784</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139784"/>
		<updated>2021-10-21T02:54:10Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and a participant associated with that assignment &lt;br /&gt;
* The due date for the assignment is approaching&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/111 - &lt;br /&gt;
&amp;quot;E-mails about reviews should direct the user to the page where the review is found. Deadline reminders should include a link on where to go to perform the needed function.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when assignment reminder emails are sent to students, they should include a link to the relevant assignment. &lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139761</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139761"/>
		<updated>2021-10-21T02:43:23Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139758</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139758"/>
		<updated>2021-10-21T02:41:49Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the expertiza/app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the expertiza/spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when new user needs to be created' do&lt;br /&gt;
  let(:row) do&lt;br /&gt;
    {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:attributes) do&lt;br /&gt;
    {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
      email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
  end&lt;br /&gt;
  let(:test_user) do&lt;br /&gt;
    {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
  end&lt;br /&gt;
  it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
    ActionMailer::Base.deliveries.clear&lt;br /&gt;
    allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
    allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
      test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
      test_user.id = 123&lt;br /&gt;
      test_user.save!&lt;br /&gt;
      test_user&lt;br /&gt;
    end&lt;br /&gt;
    #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
    allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
    allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
    allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
    allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
    expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139757</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139757"/>
		<updated>2021-10-21T02:41:21Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the expertiza/app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This functionality is also completely tested in the expertiza/spec/models/assignment_participant_spec.rb file show below. This test shows that when the import function is called an email is delivered.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''assignment_participant_spec.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      context 'when new user needs to be created' do&lt;br /&gt;
        let(:row) do&lt;br /&gt;
          {name: 'no one', fullname: 'no one', email: 'name@email.com', role:'user_role_name', parent: 'user_parent_name'}&lt;br /&gt;
        end&lt;br /&gt;
        let(:attributes) do&lt;br /&gt;
          {role_id: 1, name: 'no one', fullname: 'no one', email: 'name@email.com', email_on_submission: 'name@email.com',&lt;br /&gt;
           email_on_review: 'name@email.com', email_on_review_of_review: 'name@email.com'}&lt;br /&gt;
        end&lt;br /&gt;
        let(:test_user) do&lt;br /&gt;
          {name: 'abc', email: 'abcbbc@gmail.com'}&lt;br /&gt;
        end&lt;br /&gt;
        it 'create the user and number of mails sent should be 1' do&lt;br /&gt;
          ActionMailer::Base.deliveries.clear&lt;br /&gt;
          allow(ImportFileHelper).to receive(:define_attributes).with(row).and_return(attributes)&lt;br /&gt;
          allow(ImportFileHelper).to receive(:create_new_user) do&lt;br /&gt;
            test_user = User.new(name: 'abc', fullname: 'abc bbc', email: 'abcbbc@gmail.com')&lt;br /&gt;
            test_user.id = 123&lt;br /&gt;
            test_user.save!&lt;br /&gt;
            test_user&lt;br /&gt;
          end&lt;br /&gt;
          #allow(ImportFileHelper).to receive(:create_new_user).with(attributes, {}).and_return()&lt;br /&gt;
          allow(Assignment).to receive(:find).with(1).and_return(assignment)&lt;br /&gt;
          allow(User).to receive(:exists?).with(name: 'no one').and_return(false)&lt;br /&gt;
          allow(participant).to receive(:set_handle).and_return('handle')&lt;br /&gt;
          allow(AssignmentParticipant).to receive(:exists?).and_return(false)&lt;br /&gt;
          allow(AssignmentParticipant).to receive(:create).and_return(participant)&lt;br /&gt;
          allow(AssignmentParticipant).to receive(:set_handle)&lt;br /&gt;
          expect{(AssignmentParticipant.import(row, nil, {}, 1))}.to change { ActionMailer::Base.deliveries.count }.by(1)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139750</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139750"/>
		<updated>2021-10-21T02:38:23Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the expertiza/app/models/user.rb file.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This line calls the 'email_welcome' function every time a user is created, which sends a welcome email to the newly created user.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# Function which has a MailerHelper which sends the mail welcome email to the user after signing up&lt;br /&gt;
def email_welcome&lt;br /&gt;
  #this will send an account creation notification to user via email.&lt;br /&gt;
  MailerHelper.send_mail_to_user(self, &amp;quot;Your Expertiza account and password has been created&amp;quot;, &amp;quot;user_welcome&amp;quot;, password).deliver_now&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139741</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139741"/>
		<updated>2021-10-21T02:32:29Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the expertiza/app/models/user.rb file shown below.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139740</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139740"/>
		<updated>2021-10-21T02:32:15Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the expertiza/app/models/user.rb file shown below.&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139738</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139738"/>
		<updated>2021-10-21T02:31:02Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the user.rb file shown below.&amp;lt;br&amp;gt;'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139733</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139733"/>
		<updated>2021-10-21T02:29:55Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the user.rb file shown below.&lt;br /&gt;
'''user.rb'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
after_create :email_welcome&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139732</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139732"/>
		<updated>2021-10-21T02:28:05Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
This behavior was actually already implemented through one simple line in the user.rb file shown below.&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139731</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139731"/>
		<updated>2021-10-21T02:27:05Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/717 - &lt;br /&gt;
&amp;quot;When students' accounts are created by importing a CSV on the Users page, they receive e-mails with their user-ID and password. But if an account is created by adding them as participants to an assignment when they don't already have an account, e-mail is not sent. Students should receive e-mails upon account creation, regardless of how their account is created.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So, when students accounts are created in any way, they should receive a welcome email. This includes adding them through importing a CSV.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139727</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139727"/>
		<updated>2021-10-21T02:22:49Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - Send new account welcome email to user, when imported from CSV through assignment page==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There exists an assignment and an instructor&lt;br /&gt;
* The instructor navigates to the 'Manage Assignments' page&lt;br /&gt;
* The instructor clicks 'Add Participants' for the existing assignment&lt;br /&gt;
* The instructor clicks 'Import assignment participants'&lt;br /&gt;
* The instructor imports a CSV file containing a user who does not exist yet&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - Don't send email to reviewers for a new submission after review deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139691</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139691"/>
		<updated>2021-10-21T02:03:29Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
==Issue1 (717) - New user email==&lt;br /&gt;
&lt;br /&gt;
==Issue2 (345) - No submission email to reviewer after deadline has passed==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Issue3 (111) - Adding relevant links to reminder emails==&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139676</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139676"/>
		<updated>2021-10-21T01:54:34Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The following tasks were accomplished in this project:&lt;br /&gt;
&lt;br /&gt;
*Issue1: Send new account welcome email to user, when imported from CSV through assignment page.&lt;br /&gt;
*Issue2: Don't send email to reviewers for a new submission after review deadline has passed.&lt;br /&gt;
*Issue3: Adding relevant links to reminder emails.&lt;br /&gt;
&lt;br /&gt;
== Issue - Don't send email to reviewers for a new submission after the review deadline has passed ==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139673</id>
		<title>CSC/ECE 517 Fall 2021 - E2142. Improve e-mail notifications</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2142._Improve_e-mail_notifications&amp;diff=139673"/>
		<updated>2021-10-21T01:52:18Z</updated>

		<summary type="html">&lt;p&gt;Glbrook2: /* E2142. Improve e-mail notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=E2142. Improve e-mail notifications=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Brief Introduction==&lt;br /&gt;
&lt;br /&gt;
* E2142. Improve e-mail notifications&lt;br /&gt;
* The forked repository can be found at: https://github.com/griffinbrookshire/expertiza&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Issue - Don't send email to reviewers for a new submission after the review deadline has passed ==&lt;br /&gt;
&lt;br /&gt;
'''Pre conditions'''&lt;br /&gt;
* There is an assignment, a student as a participant, a participant as a reviewer who is reviewing the this particular assignment&lt;br /&gt;
* a review is made for a submission by the student&lt;br /&gt;
* review deadline has passed&lt;br /&gt;
* the student is allowed to submit after the review deadline has passed&lt;br /&gt;
&lt;br /&gt;
'''Expected Behavior'''&lt;br /&gt;
&lt;br /&gt;
Exact issue stating the expected behavior can be found at https://github.com/expertiza/expertiza/issues/345 - &lt;br /&gt;
&amp;quot;Evidently, if a submission is revised after review, the system e-mails the reviewer saying to revise the review. This is just fine ... except if the last round of review has been completed.&lt;br /&gt;
The message telling reviewers to revise their reviews should not be sent after the last review deadline has passed.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
So basically, When the student makes a new submission after the LAST review deadline has passed. The reviewer should not receive an email, asking the reviewer to update the review according to the new submission.&lt;br /&gt;
&lt;br /&gt;
'''Actual Behavior'''&lt;br /&gt;
&lt;br /&gt;
According to the current Code scenario on the beta branch '''''if the deadline has passed, a student(participant) cannot make new submissions'''''. So, automatically if the participant doe not make a new submission then the reviewer wont receive an email. So this issue does not really exist by the virtue of the state of the system.&lt;br /&gt;
the stack trace for the check if the submission is allowed or not is as follows - &lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def submission_allowed(topic_id = nil)&lt;br /&gt;
    check_condition('submission_allowed_id', topic_id)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
assignment.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def check_condition(column, topic_id = nil)&lt;br /&gt;
    next_due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    return false if next_due_date.nil?&lt;br /&gt;
    right_id = next_due_date.send column&lt;br /&gt;
    right = DeadlineRight.find(right_id)&lt;br /&gt;
    right &amp;amp;&amp;amp; (right.name == 'OK' || right.name == 'Late')&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
due_date.rb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def self.get_next_due_date(assignment_id, topic_id = nil)&lt;br /&gt;
    if Assignment.find(assignment_id).staggered_deadline?&lt;br /&gt;
      next_due_date = TopicDueDate.find_by(['parent_id = ? and due_at &amp;gt;= ?', topic_id, Time.zone.now])&lt;br /&gt;
      # if certion TopicDueDate is not exist, we should query next corresponding AssignmentDueDate.&lt;br /&gt;
      # eg. Time.now is 08/28/2016&lt;br /&gt;
      # One topic uses following deadlines:&lt;br /&gt;
      # TopicDueDate      08/01/2016&lt;br /&gt;
      # TopicDueDate      08/02/2016&lt;br /&gt;
      # TopicDueDate      08/03/2016&lt;br /&gt;
      # AssignmentDueDate 09/04/2016&lt;br /&gt;
      # In this case, we cannot find due_at later than Time.now in TopicDueDate.&lt;br /&gt;
      # So we should find next corrsponding AssignmentDueDate, starting with the 4th one, not the 1st one!&lt;br /&gt;
      if next_due_date.nil?&lt;br /&gt;
        topic_due_date_size = TopicDueDate.where(parent_id: topic_id).size&lt;br /&gt;
        following_assignment_due_dates = AssignmentDueDate.where(parent_id: assignment_id)[topic_due_date_size..-1]&lt;br /&gt;
        unless following_assignment_due_dates.nil?&lt;br /&gt;
          following_assignment_due_dates.each do |assignment_due_date|&lt;br /&gt;
            if assignment_due_date.due_at &amp;gt;= Time.zone.now&lt;br /&gt;
              next_due_date = assignment_due_date&lt;br /&gt;
              break&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      next_due_date = AssignmentDueDate.find_by(['parent_id = ? &amp;amp;&amp;amp; due_at &amp;gt;= ?', assignment_id, Time.zone.now])&lt;br /&gt;
    end&lt;br /&gt;
    next_due_date&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So this is issue is resolved by the state of the system itself.&amp;lt;br&amp;gt;&lt;br /&gt;
'''''BUT Surprisingly on beta branch Reviewers aren't getting any emails at all'''''&lt;br /&gt;
on beta branch, in submitted_content_controller, in function &amp;quot;submit_file&amp;quot;, this lines is supposed to send email to the reviewers to notify them about the new submission&lt;br /&gt;
&amp;lt;pre&amp;gt; participant.assignment.email(participant.id) rescue nil &amp;lt;/pre&amp;gt;&lt;br /&gt;
''BUT'' here email function is undefined. we checked for email function in assignment class, there was none. The error &amp;quot;undefined function on assignment&amp;quot; is always rescued and hence no errors were raised previously and hence it wasn't highlighted before. &amp;lt;br&amp;gt;&lt;br /&gt;
So, in beta branch reviewers are not being notified anytime a new submission is made to an assignment that they have previously reviewed. So we fixed that&lt;br /&gt;
Taking inspiration from the Master branch the previous team's work we added following code to send an email notifying the reviewer of an new submission.&lt;br /&gt;
&lt;br /&gt;
in submitted_content_controller.rb, in the functions, submit_file, submit_hyperlink&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Team.mail_assigned_reviewers(@participant)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
participant.rb&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def mail_assigned_reviewers()&lt;br /&gt;
    team = self.team&lt;br /&gt;
    maps = ResponseMap.where(reviewed_object_id: self.assignment.id, reviewee_id: team.id, type: 'ReviewResponseMap')&lt;br /&gt;
    unless maps.nil?&lt;br /&gt;
      maps.each do |map|&lt;br /&gt;
        reviewer = User.find(Participant.find(map.reviewer_id).user_id)&lt;br /&gt;
        Mailer.sync_message(&lt;br /&gt;
            {&lt;br /&gt;
                :to =&amp;gt; reviewer.email,&lt;br /&gt;
                subject:  &amp;quot;Assignment '#{self.assignment.name}': A submission has been updated since you last reviewed it&amp;quot;,&lt;br /&gt;
                cc: User.find_by(self.assignment.instructor_id).email,&lt;br /&gt;
                :body =&amp;gt; {&lt;br /&gt;
                    :obj_name =&amp;gt; self.assignment.name,&lt;br /&gt;
                    :link =&amp;gt; &amp;quot;https://expertiza.ncsu.edu/response/new?id=#{map.id}&amp;quot;,&lt;br /&gt;
                    :type =&amp;gt; 'submission',&lt;br /&gt;
                    :first_name =&amp;gt; ApplicationHelper::get_user_first_name(User.find(Participant.find(map.reviewer_id).user_id)),&lt;br /&gt;
                    :partial_name =&amp;gt; 'updated_submission_since_review'&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        ).deliver_now&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_plain.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&lt;br /&gt;
Hence, to update your review please click on the following link.&lt;br /&gt;
&amp;lt;% if @link != nil %&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
app/views/mailer/partials/_updated_submission_since_review_html.html.erb&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hi &amp;lt;%= @first_name %&amp;gt;,&amp;lt;/br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
  A &amp;lt;%=@type%&amp;gt; you were reviewing for Assignment '&amp;lt;%= @obj_name %&amp;gt;' has been updated since you last review.&amp;lt;br&amp;gt;&lt;br /&gt;
  Hence, to update your review please click on the following link.&amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;% if @link != nil %&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;%= @link %&amp;gt;&amp;quot;&amp;gt;&amp;lt;%= @link %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;% end %&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
added a line in app/mailers/mailer.rb &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 @link = defn[:body][:link]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Testing==&lt;br /&gt;
'''Testing Reviewe's Email manually'''&lt;br /&gt;
&lt;br /&gt;
Step 1: Create new assignment [Manage --&amp;gt; Assignment --&amp;gt; + Button (to create new assignment)]&lt;br /&gt;
&lt;br /&gt;
Step 2: Fill the details for the assignments.&lt;br /&gt;
&lt;br /&gt;
Step 3: Navigate to due dates.&lt;br /&gt;
&lt;br /&gt;
Step 4: Change the number of review rounds to 2.&lt;br /&gt;
&lt;br /&gt;
Step 5: Select &amp;quot;Yes&amp;quot; in the dropdown for review allowed during submission and select &amp;quot;Yes&amp;quot; for submission during the review.&lt;br /&gt;
&lt;br /&gt;
Step 6: Add two users to the assignment(author and reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 7: Log in with some user credentials (author credential).&lt;br /&gt;
&lt;br /&gt;
Step 8: Make a new submission to this assignment.&lt;br /&gt;
&lt;br /&gt;
Step 9: Log in with another user (reviewer).&lt;br /&gt;
&lt;br /&gt;
Step 10: Submit a review of the assignment submission.&lt;br /&gt;
&lt;br /&gt;
Step 11: Login as an author again. &lt;br /&gt;
&lt;br /&gt;
Step 12: Edit the submission.&lt;br /&gt;
&lt;br /&gt;
Step 13: After this check the mailbox of the reviewer [development mail for development].&lt;br /&gt;
&lt;br /&gt;
Step 14: Reviewer should get the mail to re-review the work.&lt;br /&gt;
&lt;br /&gt;
Step 15: Change the due date to some date and time which has passed.&lt;br /&gt;
&lt;br /&gt;
Step 16: Now the author should not be able to make a new submission.&lt;br /&gt;
&lt;br /&gt;
'''Testing Reviewe's Email via rspec'''&lt;/div&gt;</summary>
		<author><name>Glbrook2</name></author>
	</entry>
</feed>