<?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=Jtdavis9</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=Jtdavis9"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Jtdavis9"/>
	<updated>2026-08-18T07:54:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150375</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150375"/>
		<updated>2023-05-02T22:07:02Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: Added to Testing section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaires are used primarily by instructors to create question forms/ reviews, etc. As a student, you might have seen them while performing reviews for peers. The questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions and taking quizzes and surveys.  All of these are subclasses of the Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&amp;lt;br&amp;gt;&lt;br /&gt;
A Questionnaire can have multiple Questions as a part of it. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also, we notice that the Questionnaire controller has a parent-child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox, and TextArea to name a few. There are multiple type of Questionnaires like Review, MetaReview, Assignment etc.&amp;lt;br&amp;gt;&lt;br /&gt;
To sum it off, we can have many types of Questionnaires and each would have possibly multiple types of Questions. There can be numerous questionnaires of the same kind for a given Questionnaire type.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.&amp;lt;br&amp;gt;&lt;br /&gt;
This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&amp;lt;br&amp;gt;&lt;br /&gt;
The following functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. &amp;lt;br&amp;gt;&lt;br /&gt;
Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
There are multiple types of questions created based on the parameters passed by the user to the controller. This led to two things, Objects being created dynamically which might not be of the acceptable kind, and code injection, as we are using unsanitized user input. &lt;br /&gt;
&lt;br /&gt;
We have decided to use the '''Factory design''' pattern instead where we create a type of Questionnaire based on the type of parameters passed. Hence instead of multiple if/else code blocks to check the kind of input passed, we use a factory method to create and return the Questionnaire/Question object. Additionally, Instead of using if/else checks in the factory method, we opt for using a Map to match the input param to an Object type which further cleaned our code. &lt;br /&gt;
&lt;br /&gt;
We employed '''SOLID''' principles, and shifted code that pertained to Questions from Questionnaire controller to Questions controller. This helps us better adhere to the '''Single Responsibility''' principle. We also shifted the common code out of the Questionnaire controller to helper classes to make the code more '''DRY'''.&lt;br /&gt;
&lt;br /&gt;
= All Changes Implemented =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|files&amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add a factory method that creates respective object based on the parameter that is being passed&lt;br /&gt;
|We use factory method in a helper file as that removes the code for creating an object from inside a function that just uses those objects&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;save_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/9d3a846d862cfe4661c858e98902876cfe789a64 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;delete_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/669fc8e47c7a81223d48748f785af10b359f942e Commit]&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4edd184930109b920f7cf714b10dd22fd62c1f41 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor or add more comments to the following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; and the use of each cannot be easily understood&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/9edb52d359a1e341985259829bc7b4ddd224663a Commit]&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|[https://github.com/Soultrekker21/expertiza/commit/690f8afe526d79c5811dcfbbc5dad826c1fd2c7c Commit]&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code re-usability&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove the usage of if/else or switch case and use a Hash Map for questionnaire factory object creation&lt;br /&gt;
|We want to make our code more modular and extendable. Any change can be easily added to Hash Map rather than adding if else statements.&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/a24b18cb1702188a4d04483de8ca407920fef775 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove the usage of if/else or switch case and use a Hash Map for questions factory object creation&lt;br /&gt;
|We want to make our code more modular and extendable. Any change can be easily added to Hash Map rather than adding if else statements.&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/a24b18cb1702188a4d04483de8ca407920fef775 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|controller &amp;lt;code&amp;gt;advice_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|There needs to be a &amp;lt;code&amp;gt;.each&amp;lt;/code&amp;gt; after they keys are enumerated&lt;br /&gt;
|The Edit/View advice button was not working on the view where we create a questionnaire and new questions&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/690f8afe526d79c5811dcfbbc5dad826c1fd2c7c Commit]&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|file &amp;lt;code&amp;gt;routes.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add some routes so that all the new methods in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; can work&lt;br /&gt;
|Newly added functions don't have a predefined route and it must be specified&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/843a12bce18bf441c8cb7e5b2a04d905bb155418 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|file &amp;lt;code&amp;gt;routes.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add some routes so that the delete functionality works for questionnaires&lt;br /&gt;
|The existing code had the functionality implemented but the route was not configured rendered an error&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/6647464ad7c478ad7cd6ba27beecdee2cfa492f9 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|controller &amp;lt;code&amp;gt;quiz_questionnaire_controller.rb()&amp;lt;/code&amp;gt;&lt;br /&gt;
|There are multiple redirects to functions in the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|As some functions have been moved to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; they need to be refactored. &lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/7b875fbcbc0bc23db2d14280945f09c4cc968223 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|method &amp;lt;code&amp;gt;update_questionnaire_questions&amp;lt;/code&amp;gt;&lt;br /&gt;
|As per DRY, we removed the code to update the questionnaire's questions from &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; to the helper class.&lt;br /&gt;
|This will make the code more DRY and maintainable &lt;br /&gt;
|[https://github.com/Soultrekker21/expertiza/commit/b8b504aeeb459958115fa4aed4df2cc1c61ddaf3 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
      &lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;br /&gt;
'''Github''': https://github.com/Soultrekker21/expertiza &amp;lt;br&amp;gt;&lt;br /&gt;
'''Pull Request''': https://github.com/expertiza/expertiza/pull/2576 &amp;lt;br&amp;gt;&lt;br /&gt;
'''Current VCL''': http://152.7.178.100:3000/ &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;br /&gt;
&lt;br /&gt;
= Testing Implementation =&lt;br /&gt;
*Removal of create_questionnaire method test: Testing a non-existent method no longer necessary&lt;br /&gt;
*Aside from this we found that the questionnaire controller is already well tested&lt;br /&gt;
*Below is questionnaires_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questionnaires_test.jpg|1000px|center]]&lt;br /&gt;
*Below is questions_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questions_test.jpg|1000px|center]]&lt;br /&gt;
*Below is quiz_questionnaires_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_quiz_questionnaries_test.jpg|1000px|center]]&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2326_quiz_questionnaries_test.jpg&amp;diff=150374</id>
		<title>File:E2326 quiz questionnaries test.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2326_quiz_questionnaries_test.jpg&amp;diff=150374"/>
		<updated>2023-05-02T22:04:56Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150367</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150367"/>
		<updated>2023-05-02T21:56:00Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* All Changes Implemented */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaires are used primarily by instructors to create question forms/ reviews, etc. As a student, you might have seen them while performing reviews for peers. The questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions and taking quizzes and surveys.  All of these are subclasses of the Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&amp;lt;br&amp;gt;&lt;br /&gt;
A Questionnaire can have multiple Questions as a part of it. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also, we notice that the Questionnaire controller has a parent-child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox, and TextArea to name a few. There are multiple type of Questionnaires like Review, MetaReview, Assignment etc.&amp;lt;br&amp;gt;&lt;br /&gt;
To sum it off, we can have many types of Questionnaires and each would have possibly multiple types of Questions. There can be numerous questionnaires of the same kind for a given Questionnaire type.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.&amp;lt;br&amp;gt;&lt;br /&gt;
This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&amp;lt;br&amp;gt;&lt;br /&gt;
The following functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. &amp;lt;br&amp;gt;&lt;br /&gt;
Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
There are multiple types of questions created based on the parameters passed by the user to the controller. This led to two things, Objects being created dynamically which might not be of the acceptable kind, and code injection, as we are using unsanitized user input. &lt;br /&gt;
&lt;br /&gt;
We have decided to use the '''Factory design''' pattern instead where we create a type of Questionnaire based on the type of parameters passed. Hence instead of multiple if/else code blocks to check the kind of input passed, we use a factory method to create and return the Questionnaire/Question object. Additionally, Instead of using if/else checks in the factory method, we opt for using a Map to match the input param to an Object type which further cleaned our code. &lt;br /&gt;
&lt;br /&gt;
We employed '''SOLID''' principles, and shifted code that pertained to Questions from Questionnaire controller to Questions controller. This helps us better adhere to the '''Single Responsibility''' principle. We also shifted the common code out of the Questionnaire controller to helper classes to make the code more '''DRY'''.&lt;br /&gt;
&lt;br /&gt;
= All Changes Implemented =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|files&amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add a factory method that creates respective object based on the parameter that is being passed&lt;br /&gt;
|We use factory method in a helper file as that removes the code for creating an object from inside a function that just uses those objects&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;save_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/9d3a846d862cfe4661c858e98902876cfe789a64 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;delete_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/669fc8e47c7a81223d48748f785af10b359f942e Commit]&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4edd184930109b920f7cf714b10dd22fd62c1f41 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor or add more comments to the following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; and the use of each cannot be easily understood&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/9edb52d359a1e341985259829bc7b4ddd224663a Commit]&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|[https://github.com/Soultrekker21/expertiza/commit/690f8afe526d79c5811dcfbbc5dad826c1fd2c7c Commit]&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code re-usability&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove the usage of if/else or switch case and use a Hash Map for questionnaire factory object creation&lt;br /&gt;
|We want to make our code more modular and extendable. Any change can be easily added to Hash Map rather than adding if else statements.&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/a24b18cb1702188a4d04483de8ca407920fef775 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove the usage of if/else or switch case and use a Hash Map for questions factory object creation&lt;br /&gt;
|We want to make our code more modular and extendable. Any change can be easily added to Hash Map rather than adding if else statements.&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/a24b18cb1702188a4d04483de8ca407920fef775 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|controller &amp;lt;code&amp;gt;advice_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|There needs to be a &amp;lt;code&amp;gt;.each&amp;lt;/code&amp;gt; after they keys are enumerated&lt;br /&gt;
|The Edit/View advice button was not working on the view where we create a questionnaire and new questions&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/690f8afe526d79c5811dcfbbc5dad826c1fd2c7c Commit]&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|file &amp;lt;code&amp;gt;routes.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add some routes so that all the new methods in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; can work&lt;br /&gt;
|Newly added functions don't have a predefined route and it must be specified&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/843a12bce18bf441c8cb7e5b2a04d905bb155418 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|file &amp;lt;code&amp;gt;routes.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add some routes so that the delete functionality works for questionnaires&lt;br /&gt;
|The existing code had the functionality implemented but the route was not configured that rendered an error&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/6647464ad7c478ad7cd6ba27beecdee2cfa492f9 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|controller &amp;lt;code&amp;gt;quiz_questionnaire_controller.rb()&amp;lt;/code&amp;gt;&lt;br /&gt;
|There are multiple redirects to functions in the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|As some functions have been moved to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; they need to be refactored. &lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/7b875fbcbc0bc23db2d14280945f09c4cc968223 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
      &lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;br /&gt;
&lt;br /&gt;
= Testing Implementation =&lt;br /&gt;
*Removal of create_questionnaire method test: Testing a non-existent method no longer necessary&lt;br /&gt;
*Aside from this we found that the questionnaire controller is already well tested&lt;br /&gt;
*Below is questionnaires_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questionnaires_test.jpg|1000px|center]]&lt;br /&gt;
*Below is questions_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questions_test.jpg|1000px|center]]&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150366</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150366"/>
		<updated>2023-05-02T21:55:38Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: Fixed links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaires are used primarily by instructors to create question forms/ reviews, etc. As a student, you might have seen them while performing reviews for peers. The questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions and taking quizzes and surveys.  All of these are subclasses of the Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&amp;lt;br&amp;gt;&lt;br /&gt;
A Questionnaire can have multiple Questions as a part of it. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also, we notice that the Questionnaire controller has a parent-child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox, and TextArea to name a few. There are multiple type of Questionnaires like Review, MetaReview, Assignment etc.&amp;lt;br&amp;gt;&lt;br /&gt;
To sum it off, we can have many types of Questionnaires and each would have possibly multiple types of Questions. There can be numerous questionnaires of the same kind for a given Questionnaire type.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.&amp;lt;br&amp;gt;&lt;br /&gt;
This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&amp;lt;br&amp;gt;&lt;br /&gt;
The following functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. &amp;lt;br&amp;gt;&lt;br /&gt;
Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
There are multiple types of questions created based on the parameters passed by the user to the controller. This led to two things, Objects being created dynamically which might not be of the acceptable kind, and code injection, as we are using unsanitized user input. &lt;br /&gt;
&lt;br /&gt;
We have decided to use the '''Factory design''' pattern instead where we create a type of Questionnaire based on the type of parameters passed. Hence instead of multiple if/else code blocks to check the kind of input passed, we use a factory method to create and return the Questionnaire/Question object. Additionally, Instead of using if/else checks in the factory method, we opt for using a Map to match the input param to an Object type which further cleaned our code. &lt;br /&gt;
&lt;br /&gt;
We employed '''SOLID''' principles, and shifted code that pertained to Questions from Questionnaire controller to Questions controller. This helps us better adhere to the '''Single Responsibility''' principle. We also shifted the common code out of the Questionnaire controller to helper classes to make the code more '''DRY'''.&lt;br /&gt;
&lt;br /&gt;
= All Changes Implemented =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|files&amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add a factory method that creates respective object based on the parameter that is being passed&lt;br /&gt;
|We use factory method in a helper file as that removes the code for creating an object from inside a function that just uses those objects&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;save_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/9d3a846d862cfe4661c858e98902876cfe789a64 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;delete_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/669fc8e47c7a81223d48748f785af10b359f942e Commit]&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4edd184930109b920f7cf714b10dd22fd62c1f41 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor or add more comments to the following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; and the use of each cannot be easily understood&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/9edb52d359a1e341985259829bc7b4ddd224663a Commit]&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|[https://github.com/Soultrekker21/expertiza/commit/690f8afe526d79c5811dcfbbc5dad826c1fd2c7c Commit]&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code re-usability&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/4721039e523505e2c07f0691d8a7d42af2dc87ba Commit]&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove the usage of if/else or switch case and use a Hash Map for questionnaire factory object creation&lt;br /&gt;
|We want to make our code more modular and extendable. Any change can be easily added to Hash Map rather than adding if else statements.&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/a24b18cb1702188a4d04483de8ca407920fef775 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove the usage of if/else or switch case and use a Hash Map for questions factory object creation&lt;br /&gt;
|We want to make our code more modular and extendable. Any change can be easily added to Hash Map rather than adding if else statements.&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/a24b18cb1702188a4d04483de8ca407920fef775 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|controller &amp;lt;code&amp;gt;advice_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|There needs to be a &amp;lt;code&amp;gt;.each&amp;lt;/code&amp;gt; after they keys are enumerated&lt;br /&gt;
|The Edit/View advice button was not working on the view where we create a questionnaire and new questions&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/690f8afe526d79c5811dcfbbc5dad826c1fd2c7c Commit]&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|file &amp;lt;code&amp;gt;routes.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add some routes so that all the new methods in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; can work&lt;br /&gt;
|Newly added functions don't have a predefined route and it must be specified&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/843a12bce18bf441c8cb7e5b2a04d905bb155418 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|file &amp;lt;code&amp;gt;routes.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Add some routes so that the delete functionality works for questionnaires&lt;br /&gt;
|The existing code had the functionality implemented but the route was not configured that rendered an error&lt;br /&gt;
|[https://github.com/SoulTrekker21/expertiza/commit/6647464ad7c478ad7cd6ba27beecdee2cfa492f9 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|controller &amp;lt;code&amp;gt;quiz_questionnaire_controller.rb()&amp;lt;/code&amp;gt;&lt;br /&gt;
|There are multiple redirects to functions in the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|As some functions have been moved to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; they need to be refactored. &lt;br /&gt;
|[Commit link https://github.com/SoulTrekker21/expertiza/commit/7b875fbcbc0bc23db2d14280945f09c4cc968223 commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
      &lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;br /&gt;
&lt;br /&gt;
= Testing Implementation =&lt;br /&gt;
*Removal of create_questionnaire method test: Testing a non-existent method no longer necessary&lt;br /&gt;
*Aside from this we found that the questionnaire controller is already well tested&lt;br /&gt;
*Below is questionnaires_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questionnaires_test.jpg|1000px|center]]&lt;br /&gt;
*Below is questions_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questions_test.jpg|1000px|center]]&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150349</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150349"/>
		<updated>2023-05-02T19:31:14Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: Testing images&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
We can see that a Questionnaire can have multiple Questions. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also we notice that Questionnaire controler has a parent child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox and TextArea to name a few.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&lt;br /&gt;
the functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
There are multiple types of questions created based on the parameters passed by the user to the controller. This led to two things, Objects being created dynamically which might not be of the acceptable kind, and code injection, as we are using unsanitized user input. &lt;br /&gt;
&lt;br /&gt;
We have decided to use the '''Factory design''' pattern instead where we create a type of Questionnaire based on the type of parameters passed. Hence instead of multiple if/else code blocks to check the kind of input passed, we use a factory method to create and return the Questionnaire/Question object. Additionally, Instead of using if/else checks in the factory method, we opt for using a Map to match the input param to an Object type which further cleaned our code. &lt;br /&gt;
&lt;br /&gt;
We employed '''SOLID''' principles, and shifted code that pertained to Questions from Questionnaire controller to Questions controller. This helps us better adhere to the '''Single Responsibility''' principle. We also shifted the common code out of the Questionnaire controller to helper classes to make the code more '''DRY'''.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|controller &amp;lt;code&amp;gt;quiz_questionnaire_controller.rb()&amp;lt;/code&amp;gt;&lt;br /&gt;
|There are multiple redirects to functions in the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|As some functions have been moved to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; they need to be refactored. &lt;br /&gt;
|[Commit link https://github.com/expertiza/expertiza/commit/7b875fbcbc0bc23db2d14280945f09c4cc968223 ]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
      &lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;br /&gt;
&lt;br /&gt;
= Testing Implementation =&lt;br /&gt;
*Removal of create_questionnaire method test: Testing a non-existent method no longer necessary&lt;br /&gt;
*Aside from this we found that the questionnaire controller is already well tested&lt;br /&gt;
*Below is questionnaires_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questionnaires_test.jpg|1000px|center]]&lt;br /&gt;
*Below is questions_controller_spec.rb tests run with &amp;lt;code&amp;gt;bundle exec rspec&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:E2326_questions_test.jpg|1000px|center]]&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2326_questions_test.jpg&amp;diff=150347</id>
		<title>File:E2326 questions test.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2326_questions_test.jpg&amp;diff=150347"/>
		<updated>2023-05-02T19:26:03Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2326_questionnaires_test.jpg&amp;diff=150346</id>
		<title>File:E2326 questionnaires test.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2326_questionnaires_test.jpg&amp;diff=150346"/>
		<updated>2023-05-02T19:25:21Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150341</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150341"/>
		<updated>2023-05-02T18:59:20Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
We can see that a Questionnaire can have multiple Questions. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also we notice that Questionnaire controler has a parent child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox and TextArea to name a few.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&lt;br /&gt;
the functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
We have decided to used the Factory design pattern where we create a type of Questionnaire based on the type of parameters passed. The earlier code was using multiple if else statements to check the parameter passed and then create the required object.\\&lt;br /&gt;
In the current code we give a call to a helper function in the &amp;lt;file name&amp;gt; file and expect it to return the object based on the string parameter passed.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
      &lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;br /&gt;
&lt;br /&gt;
= Testing Implementation =&lt;br /&gt;
*Removal of create_questionnaire method test: Testing a non-existent method no longer necessary&lt;br /&gt;
*Aside from this we found that the questionnaire controller is already well tested&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150340</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150340"/>
		<updated>2023-05-02T18:49:33Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* Sample of Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
We can see that a Questionnaire can have multiple Questions. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also we notice that Questionnaire controler has a parent child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox and TextArea to name a few.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&lt;br /&gt;
the functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
We have decided to used the Factory design pattern where we create a type of Questionnaire based on the type of parameters passed. The earlier code was using multiple if else statements to check the parameter passed and then create the required object.\\&lt;br /&gt;
In the current code we give a call to a helper function in the &amp;lt;file name&amp;gt; file and expect it to return the object based on the string parameter passed.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
      &lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150339</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150339"/>
		<updated>2023-05-02T18:48:19Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* Sample of Code Changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
We can see that a Questionnaire can have multiple Questions. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also we notice that Questionnaire controler has a parent child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox and TextArea to name a few.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&lt;br /&gt;
the functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
We have decided to used the Factory design pattern where we create a type of Questionnaire based on the type of parameters passed. The earlier code was using multiple if else statements to check the parameter passed and then create the required object.\\&lt;br /&gt;
In the current code we give a call to a helper function in the &amp;lt;file name&amp;gt; file and expect it to return the object based on the string parameter passed.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
      &lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
=== Important links ===&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150338</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150338"/>
		<updated>2023-05-02T18:48:00Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: code changes added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
We can see that a Questionnaire can have multiple Questions. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also we notice that Questionnaire controler has a parent child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox and TextArea to name a few.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&lt;br /&gt;
the functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
We have decided to used the Factory design pattern where we create a type of Questionnaire based on the type of parameters passed. The earlier code was using multiple if else statements to check the parameter passed and then create the required object.\\&lt;br /&gt;
In the current code we give a call to a helper function in the &amp;lt;file name&amp;gt; file and expect it to return the object based on the string parameter passed.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
*Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*advice_controller.rb lines 57-64:  keys &amp;amp;&amp;amp; each_key methods return incorrectly, keys.each is proper syntax for this functionality&lt;br /&gt;
before:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
      	 QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end &lt;br /&gt;
after:&lt;br /&gt;
  unless params[:advice].nil?&lt;br /&gt;
    	 params[:advice].keys.each do |advice_key|&lt;br /&gt;
      	 # Updates the advice corresponding to the key&lt;br /&gt;
         QuestionAdvice.update(advice_key, advice: params[:advice] [advice_key.to_sym] [:advice])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Questionnaires_controller.rb lines 89-99: removal of create_questionnaires method due to it having identical functionality to create&lt;br /&gt;
The following method was deleted&lt;br /&gt;
  def create_questionnaire&lt;br /&gt;
    @questionnaire = Object.const_get(params[:questionnaire][:type]).new(questionnaire_params)&lt;br /&gt;
    # Create Quiz content has been moved to Quiz Questionnaire Controller&lt;br /&gt;
    if @questionnaire.type != 'QuizQuestionnaire' # checking if it is a quiz questionnaire&lt;br /&gt;
      @questionnaire.instructor_id = Ta.get_my_instructor(session[:user].id) if session[:user].role.name == 'Teaching Assistant'&lt;br /&gt;
      save&lt;br /&gt;
&lt;br /&gt;
      redirect_to controller: 'tree_display', action: 'list'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
=== Important links ===&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150337</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150337"/>
		<updated>2023-05-02T18:38:56Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: code changes added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
We can see that a Questionnaire can have multiple Questions. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also we notice that Questionnaire controler has a parent child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox and TextArea to name a few.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&lt;br /&gt;
the functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
We have decided to used the Factory design pattern where we create a type of Questionnaire based on the type of parameters passed. The earlier code was using multiple if else statements to check the parameter passed and then create the required object.\\&lt;br /&gt;
In the current code we give a call to a helper function in the &amp;lt;file name&amp;gt; file and expect it to return the object based on the string parameter passed.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Sample of Code Changes = &lt;br /&gt;
* Questionnaire Factory where the object is created with switch case using a HashMap in &amp;lt;code&amp;gt;questionnaire_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type &lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Question Factory where the questions object is created using a HashMap in &amp;lt;code&amp;gt;question_helper.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
&lt;br /&gt;
  # Class variables - used questionnaires_controller.rb to set the parameters for a question.&lt;br /&gt;
  MAX_LABEL = 'Strongly agree'.freeze&lt;br /&gt;
  MIN_LABEL = 'Strongly disagree'.freeze&lt;br /&gt;
  SIZES = { 'Criterion' =&amp;gt; '50, 3', 'Cake' =&amp;gt; '50, 3', 'TextArea' =&amp;gt; '60, 5', 'TextField' =&amp;gt; '30' }.freeze&lt;br /&gt;
  ALTERNATIVES = { 'Dropdown' =&amp;gt; '0|1|2|3|4|5' }.freeze&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
  # Assigns corrresponding variables to questionnaire object.&lt;br /&gt;
  def set_questionnaire_parameters(private_flag, display)&lt;br /&gt;
    @questionnaire.private = private_flag&lt;br /&gt;
    @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
    @questionnaire.instructor_id = session[:user].id&lt;br /&gt;
    @questionnaire.min_question_score = params[:questionnaire][:min_question_score]&lt;br /&gt;
    @questionnaire.max_question_score = params[:questionnaire][:max_question_score]&lt;br /&gt;
    @questionnaire.type = params[:questionnaire][:type]&lt;br /&gt;
    @questionnaire.display_type = display&lt;br /&gt;
    @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
    @questionnaire.save&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150336</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=150336"/>
		<updated>2023-05-02T18:32:26Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
We can see that a Questionnaire can have multiple Questions. These questionnaires can be used as a part of an assignment.&lt;br /&gt;
Also we notice that Questionnaire controler has a parent child relationship with the QuizQuestionnaire controller. There are multiple types of questions that can be added to a questionnaire like Criterion, Dropdown, Checkbox and TextArea to name a few.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt; has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller which is fully developed.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
In the present code we see that the &amp;lt;code&amp;gt;questionnaire_controller.rb&amp;lt;/code&amp;gt; has multiple non CRUD methods that should have been in the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;. Our priority is to refactor these functions to the &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt; so that we maintain the Single responsibility in the SOLID principles. We also notice that there are 2 places where there is code that is repeating itself so we extract the common code into a helper function to make the code more DRY.&lt;br /&gt;
the functions that need refactoring-&lt;br /&gt;
* &amp;lt;code&amp;gt;def delete_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def question_params&amp;lt;/code&amp;gt;  Move to questions_controller?&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_all_questions&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_new_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
* &amp;lt;code&amp;gt;def save_questions(questionnaire_id)&amp;lt;/code&amp;gt;  Move to questions_controller&lt;br /&gt;
&lt;br /&gt;
We also noticed that there were many places that used constants like the text file are size or the default min and max scores being hard coded. This makes the code not suitable for extension as any change would need to be refactored in multiple places and break code easily. Thus we plan to modify the &amp;lt;code&amp;gt; models/questions.rb&amp;lt;/code&amp;gt; and add the constants there so that all files related to questions can have access to these constants. This would make the refactoring process very easy.&lt;br /&gt;
&lt;br /&gt;
= Design Pattern Used =&lt;br /&gt;
&lt;br /&gt;
We have decided to used the Factory design pattern where we create a type of Questionnaire based on the type of parameters passed. The earlier code was using multiple if else statements to check the parameter passed and then create the required object.\\&lt;br /&gt;
In the current code we give a call to a helper function in the &amp;lt;file name&amp;gt; file and expect it to return the object based on the string parameter passed.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Some Code Samples = &lt;br /&gt;
* Questionnaire Factory where the object is created with switch case using a HashMap &lt;br /&gt;
&lt;br /&gt;
  #Map type to questionnaire&lt;br /&gt;
  QUESTIONNAIRE_MAP = {&lt;br /&gt;
    'ReviewQuestionnaire' =&amp;gt; ReviewQuestionnaire,&lt;br /&gt;
    'MetareviewQuestionnaire' =&amp;gt; MetareviewQuestionnaire,&lt;br /&gt;
    'AuthorFeedbackQuestionnaire' =&amp;gt; AuthorFeedbackQuestionnaire,&lt;br /&gt;
    'TeammateReviewQuestionnaire' =&amp;gt; TeammateReviewQuestionnaire,&lt;br /&gt;
    'AssignmentSurveyQuestionnaire' =&amp;gt; AssignmentSurveyQuestionnaire,&lt;br /&gt;
    'SurveyQuestionnaire' =&amp;gt; SurveyQuestionnaire,&lt;br /&gt;
    'GlobalSurveyQuestionnaire' =&amp;gt; GlobalSurveyQuestionnaire,&lt;br /&gt;
    'CourseSurveyQuestionnaire' =&amp;gt; CourseSurveyQuestionnaire,&lt;br /&gt;
    'BookmarkRatingQuestionnaire' =&amp;gt; BookmarkRatingQuestionnaire,&lt;br /&gt;
    'QuizQuestionnaire' =&amp;gt; QuizQuestionnaire&lt;br /&gt;
  }.freeze&lt;br /&gt;
  &lt;br /&gt;
  # factory method to create the appropriate questionnaire based on the type&lt;br /&gt;
  def questionnaire_factory(type)&lt;br /&gt;
    questionnaire = QUESTIONNAIRE_MAP[type]&lt;br /&gt;
    if questionnaire.nil?&lt;br /&gt;
      flash[:error] = 'Error: Undefined Questionnaire'&lt;br /&gt;
    else&lt;br /&gt;
      questionnaire.new&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Question Factory where the questions object is created using a HashMap&lt;br /&gt;
&lt;br /&gt;
 module QuestionHelper&lt;br /&gt;
   # Maps type to question&lt;br /&gt;
   QUESTION_MAP = {&lt;br /&gt;
     'Criterion' =&amp;gt; Criterion,&lt;br /&gt;
     'Scale' =&amp;gt; Scale,&lt;br /&gt;
     'Cake' =&amp;gt; Cake,&lt;br /&gt;
     'Dropdown' =&amp;gt; Dropdown,&lt;br /&gt;
     'Checkbox' =&amp;gt; Checkbox,&lt;br /&gt;
     'TextArea' =&amp;gt; TextArea,&lt;br /&gt;
     'TextField' =&amp;gt; TextField,&lt;br /&gt;
     'UploadFile' =&amp;gt; UploadFile,&lt;br /&gt;
     'SectionHeader' =&amp;gt; SectionHeader,&lt;br /&gt;
     'TableHeader' =&amp;gt; TableHeader,&lt;br /&gt;
     'ColumnHeader' =&amp;gt; ColumnHeader&lt;br /&gt;
   }.freeze&lt;br /&gt;
   &lt;br /&gt;
   # factory method to create the appropriate question based on the type&lt;br /&gt;
   def question_factory(type, questionnaire_id, seq)&lt;br /&gt;
     question_class = QUESTION_MAP[type]&lt;br /&gt;
     if question_class.nil?&lt;br /&gt;
       flash[:error] = 'Error: Undefined Question'&lt;br /&gt;
     else&lt;br /&gt;
       question_class.create(txt: '', questionnaire_id: questionnaire_id, seq: seq, type: type, break_before: true)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;models/question.rb&amp;lt;/code&amp;gt; that shows how the constants are used to store the parameters that would be used for object creation&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;def set_questionnaire_parameters&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
Pull Request: https://github.com/expertiza/expertiza/pull/2576&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149369</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149369"/>
		<updated>2023-04-09T01:17:03Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Proposed Design Changes =&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor large methods&lt;br /&gt;
|Create, update, and delete are noticeably larger than most methods &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149368</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149368"/>
		<updated>2023-04-09T01:12:58Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added late&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ani ==&lt;br /&gt;
&lt;br /&gt;
'''questionnaires_controller.rb'''&lt;br /&gt;
&lt;br /&gt;
- Update the Create Method as it's too long and needs to be refactored. One way to do this is by breaking it down into smaller, more manageable methods. we can create separate methods to handle different parts of the creation process, such as one method to handle validation, one method to handle saving the questionnaire to the database, etc. &lt;br /&gt;
&lt;br /&gt;
- Update confusing names: To avoid confusion, it's important to give methods and controllers descriptive names that accurately reflect their functionality and if there is another method with a similar name that performs a similar function, it should be renamed to avoid confusion. Ex. Create and Create_Questionare&lt;br /&gt;
&lt;br /&gt;
- Unused methods should be removed. ( ex. create_questionnaire)&lt;br /&gt;
&lt;br /&gt;
- Magic Strings should be declared globally or as a configuration: Magic strings, or hard-coded string values in the code, can be difficult to maintain and debug. To avoid this, we can declare them globally or as a configuration in the application. This makes it easier to manage and update these values in one place.&lt;br /&gt;
&lt;br /&gt;
'''Factory methods for question and questionare'''&lt;br /&gt;
&lt;br /&gt;
- previous PRs employed the Factory method for questions and questionnaire object creation which can be used for more readable code.&lt;br /&gt;
&lt;br /&gt;
- There are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
&lt;br /&gt;
== Jacob ==&lt;br /&gt;
*Comments still need to be removed in create function&lt;br /&gt;
&lt;br /&gt;
*questionnaire helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*question helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*save_all_questions &lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149367</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149367"/>
		<updated>2023-04-09T01:09:15Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ani ==&lt;br /&gt;
&lt;br /&gt;
'''questionnaires_controller.rb'''&lt;br /&gt;
&lt;br /&gt;
- Update the Create Method as it's too long and needs to be refactored. One way to do this is by breaking it down into smaller, more manageable methods. we can create separate methods to handle different parts of the creation process, such as one method to handle validation, one method to handle saving the questionnaire to the database, etc. &lt;br /&gt;
&lt;br /&gt;
- Update confusing names: To avoid confusion, it's important to give methods and controllers descriptive names that accurately reflect their functionality and if there is another method with a similar name that performs a similar function, it should be renamed to avoid confusion. Ex. Create and Create_Questionare&lt;br /&gt;
&lt;br /&gt;
- Unused methods should be removed. ( ex. create_questionnaire)&lt;br /&gt;
&lt;br /&gt;
- Magic Strings should be declared globally or as a configuration: Magic strings, or hard-coded string values in the code, can be difficult to maintain and debug. To avoid this, we can declare them globally or as a configuration in the application. This makes it easier to manage and update these values in one place.&lt;br /&gt;
&lt;br /&gt;
'''Factory methods for question and questionare'''&lt;br /&gt;
&lt;br /&gt;
- previous PRs employed the Factory method for questions and questionnaire object creation which can be used for more readable code.&lt;br /&gt;
&lt;br /&gt;
- There are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
&lt;br /&gt;
== Jacob ==&lt;br /&gt;
*Comments still need to be removed in create function&lt;br /&gt;
&lt;br /&gt;
*questionnaire helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*question helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*save_all_questions &lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149366</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149366"/>
		<updated>2023-04-09T01:09:04Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /*added to table*/&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
== Tushar ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|File &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Move save_all_questions(), delete_questions(), save_new_questions(), save_questions()&lt;br /&gt;
|To be consistent with SOLID principle, these methods belong in questions_controller.rb&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ani ==&lt;br /&gt;
&lt;br /&gt;
'''questionnaires_controller.rb'''&lt;br /&gt;
&lt;br /&gt;
- Update the Create Method as it's too long and needs to be refactored. One way to do this is by breaking it down into smaller, more manageable methods. we can create separate methods to handle different parts of the creation process, such as one method to handle validation, one method to handle saving the questionnaire to the database, etc. &lt;br /&gt;
&lt;br /&gt;
- Update confusing names: To avoid confusion, it's important to give methods and controllers descriptive names that accurately reflect their functionality and if there is another method with a similar name that performs a similar function, it should be renamed to avoid confusion. Ex. Create and Create_Questionare&lt;br /&gt;
&lt;br /&gt;
- Unused methods should be removed. ( ex. create_questionnaire)&lt;br /&gt;
&lt;br /&gt;
- Magic Strings should be declared globally or as a configuration: Magic strings, or hard-coded string values in the code, can be difficult to maintain and debug. To avoid this, we can declare them globally or as a configuration in the application. This makes it easier to manage and update these values in one place.&lt;br /&gt;
&lt;br /&gt;
'''Factory methods for question and questionare'''&lt;br /&gt;
&lt;br /&gt;
- previous PRs employed the Factory method for questions and questionnaire object creation which can be used for more readable code.&lt;br /&gt;
&lt;br /&gt;
- There are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
&lt;br /&gt;
== Jacob ==&lt;br /&gt;
*Comments still need to be removed in create function&lt;br /&gt;
&lt;br /&gt;
*questionnaire helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*question helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*save_all_questions &lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149365</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149365"/>
		<updated>2023-04-09T01:04:25Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
== Tushar ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a &lt;br /&gt;
|The &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ani ==&lt;br /&gt;
&lt;br /&gt;
'''questionnaires_controller.rb'''&lt;br /&gt;
&lt;br /&gt;
- Update the Create Method as it's too long and needs to be refactored. One way to do this is by breaking it down into smaller, more manageable methods. we can create separate methods to handle different parts of the creation process, such as one method to handle validation, one method to handle saving the questionnaire to the database, etc. &lt;br /&gt;
&lt;br /&gt;
- Update confusing names: To avoid confusion, it's important to give methods and controllers descriptive names that accurately reflect their functionality and if there is another method with a similar name that performs a similar function, it should be renamed to avoid confusion. Ex. Create and Create_Questionare&lt;br /&gt;
&lt;br /&gt;
- Unused methods should be removed. ( ex. create_questionnaire)&lt;br /&gt;
&lt;br /&gt;
- Magic Strings should be declared globally or as a configuration: Magic strings, or hard-coded string values in the code, can be difficult to maintain and debug. To avoid this, we can declare them globally or as a configuration in the application. This makes it easier to manage and update these values in one place.&lt;br /&gt;
&lt;br /&gt;
'''Factory methods for question and questionare'''&lt;br /&gt;
&lt;br /&gt;
- previous PRs employed the Factory method for questions and questionnaire object creation which can be used for more readable code.&lt;br /&gt;
&lt;br /&gt;
- There are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
&lt;br /&gt;
== Jacob ==&lt;br /&gt;
*Comments still need to be removed in create function&lt;br /&gt;
&lt;br /&gt;
*questionnaire helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*question helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*save_all_questions &lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
* Make sure that current proposed changes don't break existing test cases.&lt;br /&gt;
* Add unit test for newly proposed methods. &lt;br /&gt;
* Shift existing test cases for questionnaire_controller_spec.rb to question_controller.rb corresponding to methods that are being shifted&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149364</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149364"/>
		<updated>2023-04-09T01:01:32Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
== Tushar ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|method &amp;lt;code&amp;gt;add_new_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Store the used default value to some kind of constant in &amp;lt;code&amp;gt;questions.rb&amp;lt;/code&amp;gt;, so that they can be changed without refactoring code&lt;br /&gt;
|There are many literals used in the code and can change in future, so it is better to separate them &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a &lt;br /&gt;
|The &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|file &amp;lt;code&amp;gt;questionnaires_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|Refactor following vague method names&lt;br /&gt;
|There are confusing function names like &amp;lt;code&amp;gt;save_all_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_new_questions() &amp;lt;/code&amp;gt; ,  &amp;lt;code&amp;gt;save_questions() &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;save() &amp;lt;/code&amp;gt; &lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change &amp;lt;code&amp;gt;params[:question].keys.each&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;params[:question].each_key&amp;lt;/code&amp;gt;&lt;br /&gt;
| This will improve the performance and uses a single enumerator&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|method &amp;lt;code&amp;gt;create()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Remove parenthesis around function call on line 72 &lt;br /&gt;
|Unnecessary parenthesis&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method &amp;lt;code&amp;gt;save_all_questions()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Find a way to refactor the code by using more variables or Procs that can be reused in &amp;lt;code&amp;gt;questions_controller.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|The process of saving all questions with 2 nested do blocks is difficult to understand&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|method create&lt;br /&gt;
|Move code related to creation of tree node to different function name &amp;lt;code&amp;gt;create_tree_node()&amp;lt;/code&amp;gt;&lt;br /&gt;
|The create method is very big and this would help in readability and code reusability&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|method &amp;lt;code&amp;gt;questionnaire_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|method &amp;lt;code&amp;gt;question_helper()&amp;lt;/code&amp;gt;&lt;br /&gt;
|Change if/else to switch case and add default error checking to helper&lt;br /&gt;
|Code will be cleaner and there will needs to be catch all because there are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ani ==&lt;br /&gt;
&lt;br /&gt;
'''questionnaires_controller.rb'''&lt;br /&gt;
&lt;br /&gt;
- Update the Create Method as it's too long and needs to be refactored. One way to do this is by breaking it down into smaller, more manageable methods. we can create separate methods to handle different parts of the creation process, such as one method to handle validation, one method to handle saving the questionnaire to the database, etc. &lt;br /&gt;
&lt;br /&gt;
- Update confusing names: To avoid confusion, it's important to give methods and controllers descriptive names that accurately reflect their functionality and if there is another method with a similar name that performs a similar function, it should be renamed to avoid confusion. Ex. Create and Create_Questionare&lt;br /&gt;
&lt;br /&gt;
- Unused methods should be removed. ( ex. create_questionnaire)&lt;br /&gt;
&lt;br /&gt;
- Magic Strings should be declared globally or as a configuration: Magic strings, or hard-coded string values in the code, can be difficult to maintain and debug. To avoid this, we can declare them globally or as a configuration in the application. This makes it easier to manage and update these values in one place.&lt;br /&gt;
&lt;br /&gt;
'''Factory methods for question and questionare'''&lt;br /&gt;
&lt;br /&gt;
- previous PRs employed the Factory method for questions and questionnaire object creation which can be used for more readable code.&lt;br /&gt;
&lt;br /&gt;
- There are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
&lt;br /&gt;
== Jacob ==&lt;br /&gt;
*Comments still need to be removed in create function&lt;br /&gt;
&lt;br /&gt;
*questionnaire helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*question helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*save_all_questions &lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149361</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149361"/>
		<updated>2023-04-09T00:42:36Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* Jacob */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
== Tushar ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! File/Function !! Change Proposed !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|Refactored the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; &lt;br /&gt;
| The cur&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|&lt;br /&gt;
|Used &lt;br /&gt;
|We refa&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|&lt;br /&gt;
|Renamed variable names&lt;br /&gt;
|Some&lt;br /&gt;
|Will be added later&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|&lt;br /&gt;
|Added comments to other helper methods&lt;br /&gt;
|Some functions had no comments which were needed.&lt;br /&gt;
|Will be added later&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ani ==&lt;br /&gt;
&lt;br /&gt;
'''questionnaires_controller.rb'''&lt;br /&gt;
&lt;br /&gt;
- Update the Create Method as it's too long and needs to be refactored. One way to do this is by breaking it down into smaller, more manageable methods. we can create separate methods to handle different parts of the creation process, such as one method to handle validation, one method to handle saving the questionnaire to the database, etc. &lt;br /&gt;
&lt;br /&gt;
- Update confusing names: To avoid confusion, it's important to give methods and controllers descriptive names that accurately reflect their functionality and if there is another method with a similar name that performs a similar function, it should be renamed to avoid confusion. Ex. Create and Create_Questionare&lt;br /&gt;
&lt;br /&gt;
- Unused methods should be removed. ( ex. create_questionnaire)&lt;br /&gt;
&lt;br /&gt;
- Magic Strings should be declared globally or as a configuration: Magic strings, or hard-coded string values in the code, can be difficult to maintain and debug. To avoid this, we can declare them globally or as a configuration in the application. This makes it easier to manage and update these values in one place.&lt;br /&gt;
&lt;br /&gt;
'''Factory methods for question and questionare'''&lt;br /&gt;
&lt;br /&gt;
- previous PRs employed the Factory method for questions and questionnaire object creation which can be used for more readable code.&lt;br /&gt;
&lt;br /&gt;
- There are no default else conditions/ error checks in factories as of now.&lt;br /&gt;
&lt;br /&gt;
== Jacob ==&lt;br /&gt;
*Comments still need to be removed in create function&lt;br /&gt;
&lt;br /&gt;
*questionnaire helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*question helper needs to be case statement by type (checking same object 'type')&lt;br /&gt;
&lt;br /&gt;
*save_all_questions &lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149356</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149356"/>
		<updated>2023-04-08T23:09:50Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
== Tushar ==&lt;br /&gt;
== Ani ==&lt;br /&gt;
== Jacob ==&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149355</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149355"/>
		<updated>2023-04-08T23:09:38Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
== Tushar ==&lt;br /&gt;
==Ani ==&lt;br /&gt;
== Jacob ==&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149354</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149354"/>
		<updated>2023-04-08T22:24:52Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149353</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149353"/>
		<updated>2023-04-08T22:24:03Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149352</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149352"/>
		<updated>2023-04-08T22:23:24Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149351</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149351"/>
		<updated>2023-04-08T22:20:18Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Background =&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
= Project Purpose =&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Design =&lt;br /&gt;
&lt;br /&gt;
== Problems and planned changes ==&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
= Test Plan =&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149350</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149350"/>
		<updated>2023-04-08T22:19:51Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
= Project Overview =&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
== Project Purpose ==&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149349</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149349"/>
		<updated>2023-04-08T22:10:54Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== PROJECT OVERVIEW ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
Problem statement&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
== Work Completed ==&lt;br /&gt;
&lt;br /&gt;
=== Solutions to Problems ===&lt;br /&gt;
 solution1&lt;br /&gt;
 solution2&lt;br /&gt;
=== Testing ===&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Github: https://github.com/Soultrekker21/expertiza&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149348</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149348"/>
		<updated>2023-04-08T19:49:09Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== PROJECT OVERVIEW ==&lt;br /&gt;
&lt;br /&gt;
=== Background ===&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Problem Statement ===&lt;br /&gt;
&lt;br /&gt;
Problem statement&lt;br /&gt;
&lt;br /&gt;
== Summary of Work Needed ==&lt;br /&gt;
&lt;br /&gt;
=== Problems and planned changes ===&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
== Work Completed ==&lt;br /&gt;
&lt;br /&gt;
=== Solutions to Problems ===&lt;br /&gt;
 solution1&lt;br /&gt;
 solution2&lt;br /&gt;
=== Testing ===&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;br /&gt;
=== Important links ===&lt;br /&gt;
 Link to Github&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149347</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149347"/>
		<updated>2023-04-08T19:48:03Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
=== PROJECT OVERVIEW ===&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
Problem statement&lt;br /&gt;
&lt;br /&gt;
=== Summary of Work Needed ===&lt;br /&gt;
&lt;br /&gt;
== Problems and planned changes ==&lt;br /&gt;
problems and planned changes&lt;br /&gt;
&lt;br /&gt;
=== Work Completed ===&lt;br /&gt;
&lt;br /&gt;
== Solutions to Problems ==&lt;br /&gt;
 solution1&lt;br /&gt;
 solution2&lt;br /&gt;
== Testing ==&lt;br /&gt;
 test1&lt;br /&gt;
 test2&lt;br /&gt;
== Important links ==&lt;br /&gt;
 Link to Github&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149346</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149346"/>
		<updated>2023-04-08T19:45:19Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
=== PROJECT OVERVIEW ===&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
&lt;br /&gt;
In Expertiza, Questionnaire is the superclass for all kinds of questionnaires and rubrics—rubrics for evaluating submissions and teammate contributions, and taking quizzes and surveys.  All of these are subclasses of Questionnaire.  questionnaires_controller.rb is charged with creating, displaying, and managing Questionnaires.  Because it is used so widely, malfunctions could cause bugs in many parts of the system; hence it is especially important that the code be clear.&lt;br /&gt;
In recent years, questionnaires_controller.rb has been refactored repeatedly.  It is a lot clearer than it used to be.  But rough edges still remain.&lt;br /&gt;
Please look at the comments I made on your code.  I think it can be simplified considerably.&lt;br /&gt;
Is it really necessary to use so many instance variables?  Would temporary variables suffice?&lt;br /&gt;
question.rb contains a large number of constants.  It is not clear what they are used for.&lt;br /&gt;
I have also made several comments about how the code could be made clearer.&lt;br /&gt;
There is a questionnaires_controller, but no questions_controller.  The questionnaires_controller creates Question objects.  This is not elegant, because a controller should only create objects of one type, the type of objects it controls.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Summary of Work Needed ===&lt;br /&gt;
&lt;br /&gt;
== Problems and planned changes ==&lt;br /&gt;
&lt;br /&gt;
=== Work Completed ===&lt;br /&gt;
&lt;br /&gt;
== Solutions to Problems ==&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
== Important links ==&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149344</id>
		<title>CSC/ECE 517 Spring 2023 -E2326 Refactor questionnaires controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-E2326_Refactor_questionnaires_controller.rb&amp;diff=149344"/>
		<updated>2023-04-08T19:24:13Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: Created page with &amp;quot;=== PROJECT OVERVIEW ===&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== PROJECT OVERVIEW ===&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148624</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148624"/>
		<updated>2023-03-28T03:13:24Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Expertiza Overview ==&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open-source software written using Ruby on Rails which functions as a learning management software system. It has many different functions and abilities including the ability to create assignments, quizzes, assignment groups, and topics, and also a complete mechanism for providing peer reviews and feedback for other groups and other teammates. &lt;br /&gt;
&lt;br /&gt;
''Sidekiq is a popular open-source gem for Ruby on Rails applications that provides a simple and efficient way to perform background processing for time-consuming tasks. It uses multi-threading to handle jobs asynchronously, allowing the main application to continue running while the background jobs are executed. Sidekiq provides a queue system that manages jobs and prioritizes them based on their urgency.'' The docs can be found here [https://sidekiq.org/about.html].&lt;br /&gt;
&lt;br /&gt;
Sidekiq is used in Expertiza to schedule background tasks such as Plagiarism checks for Assignments (Similink) and the mail for assignment's due dates.  &lt;br /&gt;
&lt;br /&gt;
Based on our task prompt we understood that the create method of the assignment controller needs to be changed alongside the testing needs to be improved for sidekiq-related worker files. Also, the code should be commented more thoroughly and variable names changed to better reflect the context they are used for. &lt;br /&gt;
&lt;br /&gt;
===Prior Work===&lt;br /&gt;
&lt;br /&gt;
=== History: Previous projects ===&lt;br /&gt;
&lt;br /&gt;
 * E2253 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2253.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
 * E2144 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task]&lt;br /&gt;
 * E2273 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2273.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
&lt;br /&gt;
The latest Pull Request was not merged into the repository due to some failing tests and missing comments. &amp;lt;br&amp;gt;&lt;br /&gt;
Tests were failing in the following files-&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/controllers/assignments_controller_spec.rb&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
We try to address those failing tests and add block comments before function definition wherever needed. &amp;lt;br&amp;gt;&lt;br /&gt;
Additional testing of some related files is also in the scope of the project.&lt;br /&gt;
&lt;br /&gt;
=== Our Changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon review of previous PRs, we found that the work was thorough, albeit a few test cases were failing, and comments and methods could be refactored better. Based on the prompts we got, we focussed on refactoring the create method of assignments controller, and assignments form, along with the refactoring of sidekiq-related files.&lt;br /&gt;
  &lt;br /&gt;
Below is the summary of all the changes as part of this PR.&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Refactored the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method into multiple methods&lt;br /&gt;
| The current &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method is long and have multiple complex references and if statements. Created separate helpers to simplify complex DB context &lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Used early return in case of errors&lt;br /&gt;
|We refactored the code such that the errors like the assignment already being present or the directory already being present were caught early in the code. It leads to cleaner code as well.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/3c00648b7228eb0daf8a9afd30f8f3abfb44c2c4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Renamed variable names&lt;br /&gt;
|Some of the current variable names were ambiguous as to what they meant, &amp;lt;code&amp;gt;(cur_questionnaire, cur_due, etc.)&amp;lt;/code&amp;gt;. Renamed those names to be less ambiguous and state their function.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Added comments to other helper methods&lt;br /&gt;
|Some functions had no comments which were needed.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b72febb7f2370d6ccb0c99939500f6d36178bf00 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/mailers/mail_worker.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Removed inline comments and added block comments to the function perform&lt;br /&gt;
|Block comments before the function allows better readability and looks clean&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Moved the line to find the participants of a course inside the conditional block&lt;br /&gt;
|Earlier the list of participants of a course were found even when the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt; was  &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt;. We do find the list of emails when it is not &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt; and send emails to them.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Combined the multiple &amp;lt;code&amp;gt;attr_accessor&amp;lt;/code&amp;gt;lines into a single line&lt;br /&gt;
|Better readability and shorter function code.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|@mail object is not used as it is not reused anywhere else&lt;br /&gt;
|Any temporary variable that is used once should be avoided as it takes up valuable resources.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| Replaced ‘mailers’ with ‘jobs’ in &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; test&lt;br /&gt;
| Test was failing due to checking the wrong Sidekiq queue, currently &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; adds to job queue NOT mailers queue&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/95dcdaaa36b837df3d580f3352b8504535cc7c2e Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/models/assignment_form.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added block comments to methods and removed inline comments&lt;br /&gt;
|Better readability and looks clean&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Created &amp;lt;code&amp;gt;default_assignment_questionaire&amp;lt;/code&amp;gt; to handle creation of a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; that was originally in assignment questionnaire&lt;br /&gt;
|&amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; originally not only searched for an &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; but created one if one matching type did not exist. Now the second functionality (creating a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt;) is its own method.&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/b784e829920059cbff412ad7768833e95469ff2b Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|In line 58 of original code replaced &amp;lt;code&amp;gt;[][]&amp;lt;/code&amp;gt; method of searching with &amp;lt;code&amp;gt;.dig&amp;lt;/code&amp;gt;&lt;br /&gt;
|This particular line could throw errors and .dig is a safer way to search a table without the risk of getting nil errors&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Remove the switch case and moved code out of conditional &lt;br /&gt;
|There was repetition of code in multiple cases of switch statement. Moved them out of the case so that they are executed after the if statements.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/158bf7bc971a7bcfba7cf377cccdbdeef62cab40 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/8d78d40ea4e4035f95522e025fd08e220b8b9ce4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;find_participant_emails&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/190ca781681021f995a8a034a34bb8cede1733e3 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;email_reminder&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/53b8cf281215aeeec857886deaa2fae7998eff47 Commit]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage for some related files===&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
After making the changes to  &amp;lt;code&amp;gt;assignment_form.rb &amp;lt;/code&amp;gt; and  &amp;lt;code&amp;gt;assignment_form_spec.rb &amp;lt;/code&amp;gt; we ran the rspec tests with the command  &amp;lt;code&amp;gt;bundle exec rspec spec/models/assignment_form_spec.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:Assignment_form_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;spec/workers/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt;  ====&lt;br /&gt;
Automated testing of  &amp;lt;code&amp;gt;sidekiq_mailer_worker_spec.rb &amp;lt;/code&amp;gt; with the command  &amp;lt;code&amp;gt;bundle exec rspec spec/workers/sidekiq_mailer_worker_spec.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:mailer_spec.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
Automated testing of  &amp;lt;code&amp;gt;assignments_controller_spec.rb &amp;lt;/code&amp;gt; with the command  &amp;lt;code&amp;gt;bundle exec rspec spec/controllers/assignment_form_spec.rb &amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:Assignment_controller_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
=== Testing / Test Plan ===&lt;br /&gt;
The enhancement is tested manually and through rspec tests. &lt;br /&gt;
&lt;br /&gt;
VCL : http://152.7.178.223:8080/&lt;br /&gt;
&lt;br /&gt;
Login: instructor_Lien&lt;br /&gt;
&lt;br /&gt;
Password: password&lt;br /&gt;
&lt;br /&gt;
To Test via UI: &lt;br /&gt;
&lt;br /&gt;
1) Login to VCL with the above credentials&lt;br /&gt;
&lt;br /&gt;
2) Click on Manage tab &lt;br /&gt;
&lt;br /&gt;
3) Click on Assignments&lt;br /&gt;
&lt;br /&gt;
4) click on + to add a new assignment&lt;br /&gt;
&lt;br /&gt;
5) Create an assignment with a non-zero delay(this feature is to send a reminder email to participants of the course) in SimiCheck(this is the Plagiarism Checker that is being used) and Similarity Threshold to a non-zero. &lt;br /&gt;
&lt;br /&gt;
6) Go to the due date and add a due date for any day after the current date and timestamp. Just be sure that you have atleast 'delay'(set above while creating the assignment) number of hours left for the deadline. Or else the jobs would not be scheduled properly.&lt;br /&gt;
&lt;br /&gt;
7) Create the assignment&lt;br /&gt;
&lt;br /&gt;
8) Go to the Assignment page and add participants (ex. 'Paul' &amp;amp; 'Dan' to name a few. You can query the database and find more Students in the test database) to the assignment.&lt;br /&gt;
&lt;br /&gt;
9) Check the sidekiq dashboard [http://152.7.178.223:8080/sidekiq] page for queued jobs. Check the time left for the MailWorker that would be sending out the mails. &lt;br /&gt;
&lt;br /&gt;
10) It would be under the scheduled tab and would have 'delay' number of hours left less that the actual time left for the deadline. This indicated that the Mailer jobs is queued in a perfect way to send out reminder emails.&lt;br /&gt;
&lt;br /&gt;
=== Edge Cases ===&lt;br /&gt;
&lt;br /&gt;
Error shown in the dashboard:&lt;br /&gt;
&lt;br /&gt;
[[File: Functional_test_error.jpg|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
1) Note: In previous refactoring changes it was noted that this error is to be expected and will not affect the real Expertiza. Error is due to Simicheck Plagiarism Checker not having access to certain features in the PR build. This is currently out of the scope of the project and is yet to be implemented in totality. Also the Scheduled MailWorker that sends the email out to user would fail because of lack of SMTP authentication in the test database and environment. It is present in the production environment to which we dont have access.&lt;br /&gt;
&lt;br /&gt;
2) If setting up the environment yourself, the users table in expertiza_development DB would need to be updated and a Preferred Time needed to be added in already created users, for assignments to be saved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Commented out Tests so that the Build passed  ===&lt;br /&gt;
These are some tests that were failing and causing the build to fail. These tests that are commented out are completely un related to our project and fall way outside of our scope to go and resolve it.&amp;lt;br&amp;gt;&lt;br /&gt;
The files are-&amp;lt;br&amp;gt;&lt;br /&gt;
* ./spec/models/course_participant_spec.rb&lt;br /&gt;
*./spec/models/course_participant_spec.rb&lt;br /&gt;
*./spec/models/assignment_participant_spec.rb&lt;br /&gt;
*./spec/models/due_date_spec.rb&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Changes to Code wrt CodeClimate ===&lt;br /&gt;
* Removing duplicate Code in files related to our project&lt;br /&gt;
* Make the lines smaller if number of characters is more than 80&lt;br /&gt;
* Remove any kind of trailing spaces in the files&lt;br /&gt;
* Indentation issues were fixed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Coverage Report in the Build of the Pull Request ===&lt;br /&gt;
[[File:E2302_coveralls.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
=== Unrelated Tests that are failing ===&lt;br /&gt;
[[File:E2302_Failing.jpg|1000px]]&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:E2302_Failing.jpg&amp;diff=148621</id>
		<title>File:E2302 Failing.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:E2302_Failing.jpg&amp;diff=148621"/>
		<updated>2023-03-28T03:11:35Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Functional_test_error.jpg&amp;diff=148237</id>
		<title>File:Functional test error.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Functional_test_error.jpg&amp;diff=148237"/>
		<updated>2023-03-23T03:12:14Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: Jtdavis9 uploaded a new version of File:Functional test error.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148222</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148222"/>
		<updated>2023-03-23T03:08:51Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Expertiza Overview ==&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source software written using Ruby on Rails which functions as a learning management software system. It has man different functions and abilities including the ability to create assignments, quizzes, assignment groups and topics, and also a complete mechanism for providing peer reviews and feedback for other groups and other teammates. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Prior Work===&lt;br /&gt;
&lt;br /&gt;
=== History: Previous projects ===&lt;br /&gt;
&lt;br /&gt;
 * E2253 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2253.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
 * E2144 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task]&lt;br /&gt;
 * E2273 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2273.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
&lt;br /&gt;
The latest Pull Request was not merged into the repository due to some failing tests and missing comments. &amp;lt;br&amp;gt;&lt;br /&gt;
Tests were failing in the following files-&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/controllers/assignments_controller_spec.rb&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
We try to address those failing tests and add block comments before function definition wherever needed. &amp;lt;br&amp;gt;&lt;br /&gt;
Additional testing of some related files is also in the scope of the project.&lt;br /&gt;
&lt;br /&gt;
=== Our Changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon review of previous PRs, we found that the work was thorough, albeit a few test cases were failing, and comments and methods could be refactored better. Based on the prompts we got, we focussed on refactoring the create method of assignments controller, and assignments form, along with the refactoring of sidekiq-related files.&lt;br /&gt;
  &lt;br /&gt;
Below is the summary of all the changes as part of this PR.&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Refactored the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method into multiple methods&lt;br /&gt;
| The current &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method is long and have multiple complex references and if statements. Created separate helpers to simplify complex DB context &lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Used early return in case of errors&lt;br /&gt;
|We refactored the code such that the errors like the assignment already being present or the directory already being present were caught early in the code. It leads to cleaner code as well.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/3c00648b7228eb0daf8a9afd30f8f3abfb44c2c4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Renamed variable names&lt;br /&gt;
|Some of the current variable names were ambiguous as to what they meant, &amp;lt;code&amp;gt;(cur_questionnaire, cur_due, etc.)&amp;lt;/code&amp;gt;. Renamed those names to be less ambiguous and state their function.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Added comments to other helper methods&lt;br /&gt;
|Some functions had no comments which were needed.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b72febb7f2370d6ccb0c99939500f6d36178bf00 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/mailers/mail_worker.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Removed inline comments and added block comments to the function perform&lt;br /&gt;
|Block comments before the function allows better readability and looks clean&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Moved the line to find the participants of a course inside the conditional block&lt;br /&gt;
|Earlier the list of participants of a course were found even when the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt; was  &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt;. We do find the list of emails when it is not &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt; and send emails to them.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Combined the multiple &amp;lt;code&amp;gt;attr_accessor&amp;lt;/code&amp;gt;lines into a single line&lt;br /&gt;
|Better readability and shorter function code.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|@mail object is not used as it is not reused anywhere else&lt;br /&gt;
|Any temporary variable that is used once should be avoided as it takes up valuable resources.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| Replaced ‘mailers’ with ‘jobs’ in &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; test&lt;br /&gt;
| Test was failing due to checking the wrong Sidekiq queue, currently &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; adds to job queue NOT mailers queue&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/95dcdaaa36b837df3d580f3352b8504535cc7c2e Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/models/assignment_form.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added block comments to methods and removed inline comments&lt;br /&gt;
|Better readability and looks clean&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Created &amp;lt;code&amp;gt;default_assignment_questionaire&amp;lt;/code&amp;gt; to handle creation of a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; that was originally in assignment questionnaire&lt;br /&gt;
|&amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; originally not only searched for an &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; but created one if one matching type did not exist. Now the second functionality (creating a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt;) is its own method.&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/b784e829920059cbff412ad7768833e95469ff2b Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|In line 58 of original code replaced &amp;lt;code&amp;gt;[][]&amp;lt;/code&amp;gt; method of searching with &amp;lt;code&amp;gt;.dig&amp;lt;/code&amp;gt;&lt;br /&gt;
|This particular line could throw errors and .dig is a safer way to search a table without the risk of getting nil errors&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/8d78d40ea4e4035f95522e025fd08e220b8b9ce4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;find_participant_emails&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/190ca781681021f995a8a034a34bb8cede1733e3 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;email_reminder&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/53b8cf281215aeeec857886deaa2fae7998eff47 Commit]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage for some related files===&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
After making the changes to assignment_form and assignment_form_spec we ran the rspec tests with the command bundle exec rspec spec/models/assignment_form_spec.rb&lt;br /&gt;
[[File:Assignment_form_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
Automated testing of sidekiq_mailer_worker_spec.rb&lt;br /&gt;
[[File:mailer_spec.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt;  ====&lt;br /&gt;
Automated testing of assignments_controller_spec.rb&lt;br /&gt;
[[File:Assignment_controller_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
VCL : http://152.7.178.223:8080/&lt;br /&gt;
&lt;br /&gt;
Login: instructor_Lien&lt;br /&gt;
&lt;br /&gt;
Password: password&lt;br /&gt;
&lt;br /&gt;
To Test via UI&lt;br /&gt;
&lt;br /&gt;
1) Login to VCL&lt;br /&gt;
&lt;br /&gt;
2) Click on Manage&lt;br /&gt;
&lt;br /&gt;
3) Click on Assignments&lt;br /&gt;
&lt;br /&gt;
4) click on +&lt;br /&gt;
&lt;br /&gt;
5) Create an assignment with a non-zero delay in SimiCheck and Similarity Threshold to a non-zero. &lt;br /&gt;
&lt;br /&gt;
6) Go to the due date and add a due date for tomorrow. &lt;br /&gt;
&lt;br /&gt;
7) Create the assignment&lt;br /&gt;
&lt;br /&gt;
8) Go to the Assignment page and add participants (ex. Paul &amp;amp; Dan) to the assignment.&lt;br /&gt;
&lt;br /&gt;
9) Check the sidekiq [http://152.7.178.223:8080/sidekiq] page for queued jobs.&lt;br /&gt;
&lt;br /&gt;
Note: In previous refactoring changes it was noted that this error is to be expected and will not affect the real expertiza. Error is due to Simicheck Plagiarism Checker not having access to certain features in the PR build.  &lt;br /&gt;
&lt;br /&gt;
[[File: Functional_test_error.jpg|1000px]]&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148185</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148185"/>
		<updated>2023-03-23T02:47:49Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* spec/sidekiq_mail_worker_spec.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Expertiza Overview ==&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source software written using Ruby on Rails which functions as a learning management software system. It has man different functions and abilities including the ability to create assignments, quizzes, assignment groups and topics, and also a complete mechanism for providing peer reviews and feedback for other groups and other teammates. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Prior Work===&lt;br /&gt;
&lt;br /&gt;
=== History: Previous projects ===&lt;br /&gt;
&lt;br /&gt;
 * E2253 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2253.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
 * E2144 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task]&lt;br /&gt;
 * E2273 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2273.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
&lt;br /&gt;
The latest Pull Request was not merged into the repository due to some failing tests and missing comments. &amp;lt;br&amp;gt;&lt;br /&gt;
Tests were failing in the following files-&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/controllers/assignments_controller_spec.rb&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
We try to address those failing tests and add block comments before function definition wherever needed. &amp;lt;br&amp;gt;&lt;br /&gt;
Additional testing of some related files is also in the scope of the project.&lt;br /&gt;
&lt;br /&gt;
=== Our Changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon review of previous PRs, we found that the work was thorough, albeit a few test cases were failing, and comments and methods could be refactored better. Based on the prompts we got, we focussed on refactoring the create method of assignments controller, and assignments form, along with the refactoring of sidekiq-related files.&lt;br /&gt;
  &lt;br /&gt;
Below is the summary of all the changes as part of this PR.&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Refactored the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method into multiple methods&lt;br /&gt;
| The current &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method is long and have multiple complex references and if statements. Created separate helpers to simplify complex DB context &lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Used early return in case of errors&lt;br /&gt;
|We refactored the code such that the errors like the assignment already being present or the directory already being present were caught early in the code. It leads to cleaner code as well.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/3c00648b7228eb0daf8a9afd30f8f3abfb44c2c4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Renamed variable names&lt;br /&gt;
|Some of the current variable names were ambiguous as to what they meant, &amp;lt;code&amp;gt;(cur_questionnaire, cur_due, etc.)&amp;lt;/code&amp;gt;. Renamed those names to be less ambiguous and state their function.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Added comments to other helper methods&lt;br /&gt;
|Some functions had no comments which were needed.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b72febb7f2370d6ccb0c99939500f6d36178bf00 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/mailers/mail_worker.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Removed inline comments and added block comments to the function perform&lt;br /&gt;
|Block comments before the function allows better readability and looks clean&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Moved the line to find the participants of a course inside the conditional block&lt;br /&gt;
|Earlier the list of participants of a course were found even when the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt; was  &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt;. We do find the list of emails when it is not &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt; and send emails to them.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Combined the multiple &amp;lt;code&amp;gt;attr_accessor&amp;lt;/code&amp;gt;lines into a single line&lt;br /&gt;
|Better readability and shorter function code.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|@mail object is not used as it is not reused anywhere else&lt;br /&gt;
|Any temporary variable that is used once should be avoided as it takes up valuable resources.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| Replaced ‘mailers’ with ‘jobs’ in &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; test&lt;br /&gt;
| Test was failing due to checking the wrong Sidekiq queue, currently &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; adds to job queue NOT mailers queue&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/95dcdaaa36b837df3d580f3352b8504535cc7c2e Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/models/assignment_form.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added block comments to methods and removed inline comments&lt;br /&gt;
|Better readability and looks clean&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Created &amp;lt;code&amp;gt;default_assignment_questionaire&amp;lt;/code&amp;gt; to handle creation of a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; that was originally in assignment questionnaire&lt;br /&gt;
|&amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; originally not only searched for an &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; but created one if one matching type did not exist. Now the second functionality (creating a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt;) is its own method.&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/b784e829920059cbff412ad7768833e95469ff2b Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|In line 58 of original code replaced &amp;lt;code&amp;gt;[][]&amp;lt;/code&amp;gt; method of searching with &amp;lt;code&amp;gt;.dig&amp;lt;/code&amp;gt;&lt;br /&gt;
|This particular line could throw errors and .dig is a safer way to search a table without the risk of getting nil errors&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/8d78d40ea4e4035f95522e025fd08e220b8b9ce4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;find_participant_emails&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/190ca781681021f995a8a034a34bb8cede1733e3 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;email_reminder&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/53b8cf281215aeeec857886deaa2fae7998eff47 Commit]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage for some related files===&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
After making the changes to assignment_form and assignment_form_spec we ran the rspec tests with the command bundle exec rspec spec/models/assignment_form_spec.rb&lt;br /&gt;
[[File:Assignment_form_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
Automated testing of sidekiq_mailer_worker_spec.rb&lt;br /&gt;
[[File:mailer_spec.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt;  ====&lt;br /&gt;
Automated testing of assignments_controller_spec.rb&lt;br /&gt;
[[File:Assignment_controller_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
VCL : http://152.7.178.223:8080/&lt;br /&gt;
&lt;br /&gt;
Login: instructor_Lien&lt;br /&gt;
Password: Password&lt;br /&gt;
&lt;br /&gt;
To Test via UI&lt;br /&gt;
&lt;br /&gt;
1) Login to VCL&lt;br /&gt;
&lt;br /&gt;
2) Click on Manage&lt;br /&gt;
&lt;br /&gt;
3) Click on Assignments&lt;br /&gt;
&lt;br /&gt;
4) click on +&lt;br /&gt;
&lt;br /&gt;
5) Create an assignment with a non-zero delay in SimiCheck and Similarity Threshold to a non-zero. &lt;br /&gt;
&lt;br /&gt;
6) Go to the due date and add a due date for tomorrow. &lt;br /&gt;
&lt;br /&gt;
7) Create the assignment&lt;br /&gt;
&lt;br /&gt;
8) Go to the Assignment page and add participants to the assignment.&lt;br /&gt;
&lt;br /&gt;
9) Check the sidekiq page for queued jobs.&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148178</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148178"/>
		<updated>2023-03-23T02:43:27Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* spec/models/assignment_form_spec.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Expertiza Overview ==&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source software written using Ruby on Rails which functions as a learning management software system. It has man different functions and abilities including the ability to create assignments, quizzes, assignment groups and topics, and also a complete mechanism for providing peer reviews and feedback for other groups and other teammates. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Prior Work===&lt;br /&gt;
&lt;br /&gt;
=== History: Previous projects ===&lt;br /&gt;
&lt;br /&gt;
 * E2253 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2253.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
 * E2144 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task]&lt;br /&gt;
 * E2273 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2273.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
&lt;br /&gt;
The latest Pull Request was not merged into the repository due to some failing tests and missing comments. &amp;lt;br&amp;gt;&lt;br /&gt;
Tests were failing in the following files-&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/controllers/assignments_controller_spec.rb&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
We try to address those failing tests and add block comments before function definition wherever needed. &amp;lt;br&amp;gt;&lt;br /&gt;
Additional testing of some related files is also in the scope of the project.&lt;br /&gt;
&lt;br /&gt;
=== Our Changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon review of previous PRs, we found that the work was thorough, albeit a few test cases were failing, and comments and methods could be refactored better. Based on the prompts we got, we focussed on refactoring the create method of assignments controller, and assignments form, along with the refactoring of sidekiq-related files.&lt;br /&gt;
  &lt;br /&gt;
Below is the summary of all the changes as part of this PR.&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Refactored the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method into multiple methods&lt;br /&gt;
| The current &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method is long and have multiple complex references and if statements. Created separate helpers to simplify complex DB context &lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Used early return in case of errors&lt;br /&gt;
|We refactored the code such that the errors like the assignment already being present or the directory already being present were caught early in the code. It leads to cleaner code as well.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/3c00648b7228eb0daf8a9afd30f8f3abfb44c2c4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Renamed variable names&lt;br /&gt;
|Some of the current variable names were ambiguous as to what they meant, &amp;lt;code&amp;gt;(cur_questionnaire, cur_due, etc.)&amp;lt;/code&amp;gt;. Renamed those names to be less ambiguous and state their function.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Added comments to other helper methods&lt;br /&gt;
|Some functions had no comments which were needed.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b72febb7f2370d6ccb0c99939500f6d36178bf00 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/mailers/mail_worker.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Removed inline comments and added block comments to the function perform&lt;br /&gt;
|Block comments before the function allows better readability and looks clean&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Moved the line to find the participants of a course inside the conditional block&lt;br /&gt;
|Earlier the list of participants of a course were found even when the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt; was  &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt;. We do find the list of emails when it is not &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt; and send emails to them.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Combined the multiple &amp;lt;code&amp;gt;attr_accessor&amp;lt;/code&amp;gt;lines into a single line&lt;br /&gt;
|Better readability and shorter function code.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|@mail object is not used as it is not reused anywhere else&lt;br /&gt;
|Any temporary variable that is used once should be avoided as it takes up valuable resources.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| Replaced ‘mailers’ with ‘jobs’ in &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; test&lt;br /&gt;
| Test was failing due to checking the wrong Sidekiq queue, currently &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; adds to job queue NOT mailers queue&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/95dcdaaa36b837df3d580f3352b8504535cc7c2e Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/models/assignment_form.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added block comments to methods and removed inline comments&lt;br /&gt;
|Better readability and looks clean&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Created &amp;lt;code&amp;gt;default_assignment_questionaire&amp;lt;/code&amp;gt; to handle creation of a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; that was originally in assignment questionnaire&lt;br /&gt;
|&amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; originally not only searched for an &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; but created one if one matching type did not exist. Now the second functionality (creating a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt;) is its own method.&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/b784e829920059cbff412ad7768833e95469ff2b Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|In line 58 of original code replaced &amp;lt;code&amp;gt;[][]&amp;lt;/code&amp;gt; method of searching with &amp;lt;code&amp;gt;.dig&amp;lt;/code&amp;gt;&lt;br /&gt;
|This particular line could throw errors and .dig is a safer way to search a table without the risk of getting nil errors&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/8d78d40ea4e4035f95522e025fd08e220b8b9ce4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;find_participant_emails&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/190ca781681021f995a8a034a34bb8cede1733e3 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;email_reminder&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/53b8cf281215aeeec857886deaa2fae7998eff47 Commit]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage for some related files===&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
After making the changes to assignment_form and assignment_form_spec we ran the rspec tests with the command bundle exec rspec spec/models/assignment_form_spec.rb&lt;br /&gt;
[[File:Assignment_form_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
Automated testing of sidekiq_mailer_worker_spec.rb&lt;br /&gt;
[[File:mailer_spec.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt;  ====&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
VCL : http://152.7.177.156:8080/&lt;br /&gt;
Login: instructor_Lien&lt;br /&gt;
Password: Password&lt;br /&gt;
&lt;br /&gt;
To Test via UI&lt;br /&gt;
&lt;br /&gt;
1) Login to VCL&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148176</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148176"/>
		<updated>2023-03-23T02:41:26Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* spec/controllers/auth_controller_spec.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Expertiza Overview ==&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source software written using Ruby on Rails which functions as a learning management software system. It has man different functions and abilities including the ability to create assignments, quizzes, assignment groups and topics, and also a complete mechanism for providing peer reviews and feedback for other groups and other teammates. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Prior Work===&lt;br /&gt;
&lt;br /&gt;
=== History: Previous projects ===&lt;br /&gt;
&lt;br /&gt;
 * E2253 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2253.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
 * E2144 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task]&lt;br /&gt;
 * E2273 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2273.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
&lt;br /&gt;
The latest Pull Request was not merged into the repository due to some failing tests and missing comments. &amp;lt;br&amp;gt;&lt;br /&gt;
Tests were failing in the following files-&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/controllers/assignments_controller_spec.rb&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
We try to address those failing tests and add block comments before function definition wherever needed. &amp;lt;br&amp;gt;&lt;br /&gt;
Additional testing of some related files is also in the scope of the project.&lt;br /&gt;
&lt;br /&gt;
=== Our Changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon review of previous PRs, we found that the work was thorough, albeit a few test cases were failing, and comments and methods could be refactored better. Based on the prompts we got, we focussed on refactoring the create method of assignments controller, and assignments form, along with the refactoring of sidekiq-related files.&lt;br /&gt;
  &lt;br /&gt;
Below is the summary of all the changes as part of this PR.&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Refactored the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method into multiple methods&lt;br /&gt;
| The current &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method is long and have multiple complex references and if statements. Created separate helpers to simplify complex DB context &lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Used early return in case of errors&lt;br /&gt;
|We refactored the code such that the errors like the assignment already being present or the directory already being present were caught early in the code. It leads to cleaner code as well.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/3c00648b7228eb0daf8a9afd30f8f3abfb44c2c4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Renamed variable names&lt;br /&gt;
|Some of the current variable names were ambiguous as to what they meant, &amp;lt;code&amp;gt;(cur_questionnaire, cur_due, etc.)&amp;lt;/code&amp;gt;. Renamed those names to be less ambiguous and state their function.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Added comments to other helper methods&lt;br /&gt;
|Some functions had no comments which were needed.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b72febb7f2370d6ccb0c99939500f6d36178bf00 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/mailers/mail_worker.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Removed inline comments and added block comments to the function perform&lt;br /&gt;
|Block comments before the function allows better readability and looks clean&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Moved the line to find the participants of a course inside the conditional block&lt;br /&gt;
|Earlier the list of participants of a course were found even when the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt; was  &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt;. We do find the list of emails when it is not &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt; and send emails to them.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Combined the multiple &amp;lt;code&amp;gt;attr_accessor&amp;lt;/code&amp;gt;lines into a single line&lt;br /&gt;
|Better readability and shorter function code.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|@mail object is not used as it is not reused anywhere else&lt;br /&gt;
|Any temporary variable that is used once should be avoided as it takes up valuable resources.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| Replaced ‘mailers’ with ‘jobs’ in &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; test&lt;br /&gt;
| Test was failing due to checking the wrong Sidekiq queue, currently &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; adds to job queue NOT mailers queue&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/95dcdaaa36b837df3d580f3352b8504535cc7c2e Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/models/assignment_form.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added block comments to methods and removed inline comments&lt;br /&gt;
|Better readability and looks clean&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Created &amp;lt;code&amp;gt;default_assignment_questionaire&amp;lt;/code&amp;gt; to handle creation of a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; that was originally in assignment questionnaire&lt;br /&gt;
|&amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; originally not only searched for an &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; but created one if one matching type did not exist. Now the second functionality (creating a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt;) is its own method.&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/b784e829920059cbff412ad7768833e95469ff2b Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|In line 58 of original code replaced &amp;lt;code&amp;gt;[][]&amp;lt;/code&amp;gt; method of searching with &amp;lt;code&amp;gt;.dig&amp;lt;/code&amp;gt;&lt;br /&gt;
|This particular line could throw errors and .dig is a safer way to search a table without the risk of getting nil errors&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/8d78d40ea4e4035f95522e025fd08e220b8b9ce4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;find_participant_emails&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/190ca781681021f995a8a034a34bb8cede1733e3 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;email_reminder&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/53b8cf281215aeeec857886deaa2fae7998eff47 Commit]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage for some related files===&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
After making the changes to assignment_form and assignment_form_spec we ran the rspec tests with the command bundle exec rspec spec/models/assignment_form_spec.rb&lt;br /&gt;
[[File:Assignment_form_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt;  ====&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
VCL : http://152.7.177.156:8080/&lt;br /&gt;
Login: instructor_Lien&lt;br /&gt;
Password: Password&lt;br /&gt;
&lt;br /&gt;
To Test via UI&lt;br /&gt;
&lt;br /&gt;
1) Login to VCL&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148173</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=148173"/>
		<updated>2023-03-23T02:38:32Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: /* spec/controllers/auth_controller_spec.rb */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Expertiza Overview ==&lt;br /&gt;
&lt;br /&gt;
===Background===&lt;br /&gt;
&lt;br /&gt;
Expertiza is an open source software written using Ruby on Rails which functions as a learning management software system. It has man different functions and abilities including the ability to create assignments, quizzes, assignment groups and topics, and also a complete mechanism for providing peer reviews and feedback for other groups and other teammates. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Prior Work===&lt;br /&gt;
&lt;br /&gt;
=== History: Previous projects ===&lt;br /&gt;
&lt;br /&gt;
 * E2253 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2253.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
 * E2144 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task]&lt;br /&gt;
 * E2273 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2273.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
&lt;br /&gt;
The latest Pull Request was not merged into the repository due to some failing tests and missing comments. &amp;lt;br&amp;gt;&lt;br /&gt;
Tests were failing in the following files-&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;spec/controllers/assignments_controller_spec.rb&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
We try to address those failing tests and add block comments before function definition wherever needed. &amp;lt;br&amp;gt;&lt;br /&gt;
Additional testing of some related files is also in the scope of the project.&lt;br /&gt;
&lt;br /&gt;
=== Our Changes ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Upon review of previous PRs, we found that the work was thorough, albeit a few test cases were failing, and comments and methods could be refactored better. Based on the prompts we got, we focussed on refactoring the create method of assignments controller, and assignments form, along with the refactoring of sidekiq-related files.&lt;br /&gt;
  &lt;br /&gt;
Below is the summary of all the changes as part of this PR.&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Refactored the &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method into multiple methods&lt;br /&gt;
| The current &amp;lt;code&amp;gt;create&amp;lt;/code&amp;gt; method is long and have multiple complex references and if statements. Created separate helpers to simplify complex DB context &lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Used early return in case of errors&lt;br /&gt;
|We refactored the code such that the errors like the assignment already being present or the directory already being present were caught early in the code. It leads to cleaner code as well.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/3c00648b7228eb0daf8a9afd30f8f3abfb44c2c4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Renamed variable names&lt;br /&gt;
|Some of the current variable names were ambiguous as to what they meant, &amp;lt;code&amp;gt;(cur_questionnaire, cur_due, etc.)&amp;lt;/code&amp;gt;. Renamed those names to be less ambiguous and state their function.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/4c2f0e04e7e3ab10443af26d2868758b5c696b55 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Added comments to other helper methods&lt;br /&gt;
|Some functions had no comments which were needed.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b72febb7f2370d6ccb0c99939500f6d36178bf00 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/mailers/mail_worker.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Removed inline comments and added block comments to the function perform&lt;br /&gt;
|Block comments before the function allows better readability and looks clean&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Moved the line to find the participants of a course inside the conditional block&lt;br /&gt;
|Earlier the list of participants of a course were found even when the &amp;lt;code&amp;gt;deadline_type&amp;lt;/code&amp;gt; was  &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt;. We do find the list of emails when it is not &amp;lt;code&amp;gt;'drop_outstanding_reviews’&amp;lt;/code&amp;gt; and send emails to them.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Combined the multiple &amp;lt;code&amp;gt;attr_accessor&amp;lt;/code&amp;gt;lines into a single line&lt;br /&gt;
|Better readability and shorter function code.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|@mail object is not used as it is not reused anywhere else&lt;br /&gt;
|Any temporary variable that is used once should be avoided as it takes up valuable resources.&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/b56ecca4db6e1784a3f92b4fa9619992c1d4dcb2 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| Replaced ‘mailers’ with ‘jobs’ in &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; test&lt;br /&gt;
| Test was failing due to checking the wrong Sidekiq queue, currently &amp;lt;code&amp;gt;add_to_delayed_queue&amp;lt;/code&amp;gt; adds to job queue NOT mailers queue&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/95dcdaaa36b837df3d580f3352b8504535cc7c2e Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;app/models/assignment_form.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added block comments to methods and removed inline comments&lt;br /&gt;
|Better readability and looks clean&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Created &amp;lt;code&amp;gt;default_assignment_questionaire&amp;lt;/code&amp;gt; to handle creation of a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; that was originally in assignment questionnaire&lt;br /&gt;
|&amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; originally not only searched for an &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt; but created one if one matching type did not exist. Now the second functionality (creating a default &amp;lt;code&amp;gt;assignment_questionnaire&amp;lt;/code&amp;gt;) is its own method.&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/b784e829920059cbff412ad7768833e95469ff2b Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|In line 58 of original code replaced &amp;lt;code&amp;gt;[][]&amp;lt;/code&amp;gt; method of searching with &amp;lt;code&amp;gt;.dig&amp;lt;/code&amp;gt;&lt;br /&gt;
|This particular line could throw errors and .dig is a safer way to search a table without the risk of getting nil errors&lt;br /&gt;
|[https://github.com/expertiza/expertiza/pull/2556/commits/975312c88bb65861b1b6f2b268dc8d80c15aa501 Commit]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Changes to &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&lt;br /&gt;
! &amp;amp;nbsp;#&amp;amp;nbsp; !! Change !! Rationale !! Commit Link&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;perform&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/8d78d40ea4e4035f95522e025fd08e220b8b9ce4 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;find_participant_emails&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/190ca781681021f995a8a034a34bb8cede1733e3 Commit]&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Added test case for method &amp;lt;code&amp;gt;email_reminder&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;mail_worker.rb&amp;lt;/code&amp;gt;&lt;br /&gt;
|This test case was not implemented in the earlier Pull Request&lt;br /&gt;
|[https://github.com/tusharkini/expertiza/commit/53b8cf281215aeeec857886deaa2fae7998eff47 Commit]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Test Coverage for some related files===&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/controllers/auth_controller_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
[[File:Assignment_form_test.jpg|1000px]]&lt;br /&gt;
&lt;br /&gt;
====  &amp;lt;code&amp;gt;spec/models/assignment_form_spec.rb&amp;lt;/code&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;code&amp;gt;spec/sidekiq_mail_worker_spec.rb&amp;lt;/code&amp;gt;  ====&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Assignment_form_test.jpg&amp;diff=148172</id>
		<title>File:Assignment form test.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Assignment_form_test.jpg&amp;diff=148172"/>
		<updated>2023-03-23T02:35:58Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Mailer_spec.jpg&amp;diff=148170</id>
		<title>File:Mailer spec.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Mailer_spec.jpg&amp;diff=148170"/>
		<updated>2023-03-23T02:31:47Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Functional_test_error.jpg&amp;diff=148165</id>
		<title>File:Functional test error.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Functional_test_error.jpg&amp;diff=148165"/>
		<updated>2023-03-23T02:30:45Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Assignment_controller_test.jpg&amp;diff=148164</id>
		<title>File:Assignment controller test.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Assignment_controller_test.jpg&amp;diff=148164"/>
		<updated>2023-03-23T02:30:34Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: Jtdavis9 uploaded a new version of File:Assignment controller test.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Assignment_controller_test.jpg&amp;diff=148163</id>
		<title>File:Assignment controller test.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Assignment_controller_test.jpg&amp;diff=148163"/>
		<updated>2023-03-23T02:29:59Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=147836</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=147836"/>
		<updated>2023-03-22T15:09:19Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Topic Overview ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Prior Work===&lt;br /&gt;
&lt;br /&gt;
=== History: Previous projects ===&lt;br /&gt;
&lt;br /&gt;
 * E2253 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2253.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
 * E2144 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2144._Refactor_delayed_mailer_and_scheduled_task]&lt;br /&gt;
 * E2273 [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2022_-_E2273.Refactor_delayed_mailer.rb_and_scheduled_task.rb]&lt;br /&gt;
&lt;br /&gt;
== Our Changes ==&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=147549</id>
		<title>CSC/ECE 517 Spring 2023 - E2302</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2302&amp;diff=147549"/>
		<updated>2023-03-20T18:29:28Z</updated>

		<summary type="html">&lt;p&gt;Jtdavis9: Created page with &amp;quot;==E2302. Refactoring the Delayed Mailer and Scheduler==  __TOC__&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==E2302. Refactoring the Delayed Mailer and Scheduler==&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;/div&gt;</summary>
		<author><name>Jtdavis9</name></author>
	</entry>
</feed>