<?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=Vchheda</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=Vchheda"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Vchheda"/>
	<updated>2026-05-14T05:26:06Z</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_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150319</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150319"/>
		<updated>2023-05-01T00:52:33Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
The current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&amp;lt;br&amp;gt;&lt;br /&gt;
To get the QuestionnairesController and QuestionsController endpoints running in the reimplementation-back-end repository, we need to reimplement the respective model files and add other dependent files.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following UML diagram shows the association between models we will be working on -&lt;br /&gt;
&lt;br /&gt;
[[File:oodd_uml.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
Below is the implementation plan that we have followed for E2345:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Implement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the instructor_id with the instructor details within the questionnaire object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questionnaires = Questionnaire.order(:id)&lt;br /&gt;
    render json: @questionnaires, status: :ok and return&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire. Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire if it exists, otherwise provides with appropriate error. It should delete the questionnaire only if there are no questions associated to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.delete&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # Save questionnaire information&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.update(questionnaire_params)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def copy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.copy_questionnaire_details(params)&lt;br /&gt;
      render json: &amp;quot;Copy of the questionnaire has been created successfully.&amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*toggle_access: This is a GET endpoint that changes the access from public to private and vice versa if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def toggle_access&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.private = !@questionnaire.private&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      @access = @questionnaire.private == true ? 'private' : 'public'&lt;br /&gt;
      render json: &amp;quot;The questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been successfully made #{@access}. &amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questions = Question.order(:id)&lt;br /&gt;
    render json: @questions, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      render json: @question, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the question parameters and creates a new question. Refactor the Create endpoint in questions_controller.rb such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a question ID and deletes that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.destroy&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*delete_all: This is a DELETE endpoint that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*shiw_all: This is a GET endpoint that takes questionnaire_id as the path parameter and shows all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully displayed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def show_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questions = @questionnaire.questions&lt;br /&gt;
      render json: @questions, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.update(question_params)&lt;br /&gt;
      @question.save!&lt;br /&gt;
      render json: @question, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def types&lt;br /&gt;
    types = Question.distinct.pluck(:question_type)&lt;br /&gt;
    render json: types.to_a, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
Rspec test skeleton for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could only do manual testing of our controller endpoints using Postman. In this project, we focus to create the models required to implement CRUD operations in the reimplementation-back-end repository and test the endpoints using Swagger API.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
#rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
#RAILS_ENV=test rails rswag &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionnairesController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire (using put request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire (using put request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire (using put request) with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
|15 || Test to update the Questionnaire (using patch request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
|16 || Test to update the Questionnaire (using patch request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
|17 || Test to update the Questionnaire (using patch request) with non-existing id in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_spec_new.png|border|800px|]]  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Questionnaire_swagger_new.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionsController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question (using put request)with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question (using put request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question (using put request)with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
|15 || Test to update the Question (using patch request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
|16 || Test to update the Question (using patch request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
|17 || Test to update the Question (using patch request) with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
|18 || Test to show all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
|19 || Test to show all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_spec_new.png|border|800px|]] &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Question_swagger_new.png|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
#rspec spec/models/question_spec.rb&lt;br /&gt;
&lt;br /&gt;
'''Tests for Questionnaire model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_model_test.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for Question model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_model_test.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
*The questions and questionnaires model in the reimplementation-back-end repo has been updated to have question_type and questionnaire_type attribute instead of type attribute. Ruby has implicit inheritance when the type attribute is used. However, our repo does not have the dependent models for each type of Question and Questionnaire. For future implementation, those model classes could be added and this attribute can be refactored in the model and controller files.&lt;br /&gt;
*Implement other associations (for example: assignments) within each models.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:''' https://youtu.be/zkId16tklXI&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_swagger_new.png&amp;diff=150318</id>
		<title>File:Question swagger new.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_swagger_new.png&amp;diff=150318"/>
		<updated>2023-05-01T00:51:34Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_swagger_new.png&amp;diff=150317</id>
		<title>File:Questionnaire swagger new.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_swagger_new.png&amp;diff=150317"/>
		<updated>2023-05-01T00:51:15Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150316</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150316"/>
		<updated>2023-05-01T00:47:24Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
The current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&amp;lt;br&amp;gt;&lt;br /&gt;
To get the QuestionnairesController and QuestionsController endpoints running in the reimplementation-back-end repository, we need to reimplement the respective model files and add other dependent files.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following UML diagram shows the association between models we will be working on -&lt;br /&gt;
&lt;br /&gt;
[[File:oodd_uml.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
Below is the implementation plan that we have followed for E2345:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Implement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the instructor_id with the instructor details within the questionnaire object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questionnaires = Questionnaire.order(:id)&lt;br /&gt;
    render json: @questionnaires, status: :ok and return&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire. Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire if it exists, otherwise provides with appropriate error. It should delete the questionnaire only if there are no questions associated to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.delete&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # Save questionnaire information&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.update(questionnaire_params)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def copy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.copy_questionnaire_details(params)&lt;br /&gt;
      render json: &amp;quot;Copy of the questionnaire has been created successfully.&amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*toggle_access: This is a GET endpoint that changes the access from public to private and vice versa if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def toggle_access&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.private = !@questionnaire.private&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      @access = @questionnaire.private == true ? 'private' : 'public'&lt;br /&gt;
      render json: &amp;quot;The questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been successfully made #{@access}. &amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questions = Question.order(:id)&lt;br /&gt;
    render json: @questions, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      render json: @question, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the question parameters and creates a new question. Refactor the Create endpoint in questions_controller.rb such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a question ID and deletes that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.destroy&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*delete_all: This is a DELETE endpoint that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*shiw_all: This is a GET endpoint that takes questionnaire_id as the path parameter and shows all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully displayed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def show_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questions = @questionnaire.questions&lt;br /&gt;
      render json: @questions, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.update(question_params)&lt;br /&gt;
      @question.save!&lt;br /&gt;
      render json: @question, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def types&lt;br /&gt;
    types = Question.distinct.pluck(:question_type)&lt;br /&gt;
    render json: types.to_a, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
Rspec test skeleton for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could only do manual testing of our controller endpoints using Postman. In this project, we focus to create the models required to implement CRUD operations in the reimplementation-back-end repository and test the endpoints using Swagger API.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
#rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
#RAILS_ENV=test rails rswag &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionnairesController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire (using put request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire (using put request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire (using put request) with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
|15 || Test to update the Questionnaire (using patch request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
|16 || Test to update the Questionnaire (using patch request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
|17 || Test to update the Questionnaire (using patch request) with non-existing id in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_spec_new.png|border|800px|]]  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Questionnaire_swagger.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionsController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question (using put request)with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question (using put request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question (using put request)with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
|15 || Test to update the Question (using patch request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
|16 || Test to update the Question (using patch request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
|17 || Test to update the Question (using patch request) with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
|18 || Test to show all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
|19 || Test to show all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_spec_new.png|border|800px|]] &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Question_Swagger.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
#rspec spec/models/question_spec.rb&lt;br /&gt;
&lt;br /&gt;
'''Tests for Questionnaire model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_model_test.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for Question model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_model_test.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
*The questions and questionnaires model in the reimplementation-back-end repo has been updated to have question_type and questionnaire_type attribute instead of type attribute. Ruby has implicit inheritance when the type attribute is used. However, our repo does not have the dependent models for each type of Question and Questionnaire. For future implementation, those model classes could be added and this attribute can be refactored in the model and controller files.&lt;br /&gt;
*Implement other associations (for example: assignments) within each models.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:''' https://youtu.be/zkId16tklXI&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150315</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150315"/>
		<updated>2023-05-01T00:44:45Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
The current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&amp;lt;br&amp;gt;&lt;br /&gt;
To get the QuestionnairesController and QuestionsController endpoints running in the reimplementation-back-end repository, we need to reimplement the respective model files and add other dependent files.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following UML diagram shows the association between models we will be working on -&lt;br /&gt;
&lt;br /&gt;
[[File:oodd_uml.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
Below is the implementation plan that we have followed for E2345:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Implement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the instructor_id with the instructor details within the questionnaire object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questionnaires = Questionnaire.order(:id)&lt;br /&gt;
    render json: @questionnaires, status: :ok and return&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire. Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire if it exists, otherwise provides with appropriate error. It should delete the questionnaire only if there are no questions associated to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.delete&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # Save questionnaire information&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.update(questionnaire_params)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def copy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.copy_questionnaire_details(params)&lt;br /&gt;
      render json: &amp;quot;Copy of the questionnaire has been created successfully.&amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*toggle_access: This is a GET endpoint that changes the access from public to private and vice versa if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def toggle_access&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.private = !@questionnaire.private&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      @access = @questionnaire.private == true ? 'private' : 'public'&lt;br /&gt;
      render json: &amp;quot;The questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been successfully made #{@access}. &amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questions = Question.order(:id)&lt;br /&gt;
    render json: @questions, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      render json: @question, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the question parameters and creates a new question. Refactor the Create endpoint in questions_controller.rb such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a question ID and deletes that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.destroy&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*delete_all: This is a DELETE endpoint that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*shiw_all: This is a GET endpoint that takes questionnaire_id as the path parameter and shows all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully displayed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def show_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questions = @questionnaire.questions&lt;br /&gt;
      render json: @questions, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.update(question_params)&lt;br /&gt;
      @question.save!&lt;br /&gt;
      render json: @question, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def types&lt;br /&gt;
    types = Question.distinct.pluck(:question_type)&lt;br /&gt;
    render json: types.to_a, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
Rspec test skeleton for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could only do manual testing of our controller endpoints using Postman. In this project, we focus to create the models required to implement CRUD operations in the reimplementation-back-end repository and test the endpoints using Swagger API.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
#rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
#RAILS_ENV=test rails rswag &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionnairesController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire (using put request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire (using put request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire (using put request) with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
|15 || Test to update the Questionnaire (using patch request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
|16 || Test to update the Questionnaire (using patch request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
|17 || Test to update the Questionnaire (using patch request) with non-existing id in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_spec_new.png|border|800px|]]  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Questionnaire_swagger.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionsController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question (using put request)with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question (using put request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question (using put request)with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
|15 || Test to update the Question (using patch request) with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
|16 || Test to update the Question (using patch request) with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
|17 || Test to update the Question (using patch request) with non-existing id in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_spec_new.png|border|800px|]] &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Question_Swagger.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
#rspec spec/models/question_spec.rb&lt;br /&gt;
&lt;br /&gt;
'''Tests for Questionnaire model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_model_test.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for Question model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_model_test.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
*The questions and questionnaires model in the reimplementation-back-end repo has been updated to have question_type and questionnaire_type attribute instead of type attribute. Ruby has implicit inheritance when the type attribute is used. However, our repo does not have the dependent models for each type of Question and Questionnaire. For future implementation, those model classes could be added and this attribute can be refactored in the model and controller files.&lt;br /&gt;
*Implement other associations (for example: assignments) within each models.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:''' https://youtu.be/zkId16tklXI&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150314</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150314"/>
		<updated>2023-05-01T00:36:56Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
The current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&amp;lt;br&amp;gt;&lt;br /&gt;
To get the QuestionnairesController and QuestionsController endpoints running in the reimplementation-back-end repository, we need to reimplement the respective model files and add other dependent files.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following UML diagram shows the association between models we will be working on -&lt;br /&gt;
&lt;br /&gt;
[[File:oodd_uml.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
Below is the implementation plan that we have followed for E2345:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Implement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the instructor_id with the instructor details within the questionnaire object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questionnaires = Questionnaire.order(:id)&lt;br /&gt;
    render json: @questionnaires, status: :ok and return&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire. Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire if it exists, otherwise provides with appropriate error. It should delete the questionnaire only if there are no questions associated to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.delete&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # Save questionnaire information&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.update(questionnaire_params)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def copy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.copy_questionnaire_details(params)&lt;br /&gt;
      render json: &amp;quot;Copy of the questionnaire has been created successfully.&amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*toggle_access: This is a GET endpoint that changes the access from public to private and vice versa if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def toggle_access&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.private = !@questionnaire.private&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      @access = @questionnaire.private == true ? 'private' : 'public'&lt;br /&gt;
      render json: &amp;quot;The questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been successfully made #{@access}. &amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questions = Question.order(:id)&lt;br /&gt;
    render json: @questions, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      render json: @question, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the question parameters and creates a new question. Refactor the Create endpoint in questions_controller.rb such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a question ID and deletes that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.destroy&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*delete_all: This is a DELETE endpoint that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*shiw_all: This is a GET endpoint that takes questionnaire_id as the path parameter and shows all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully displayed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def show_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questions = @questionnaire.questions&lt;br /&gt;
      render json: @questions, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.update(question_params)&lt;br /&gt;
      @question.save!&lt;br /&gt;
      render json: @question, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def types&lt;br /&gt;
    types = Question.distinct.pluck(:question_type)&lt;br /&gt;
    render json: types.to_a, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
Rspec test skeleton for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could only do manual testing of our controller endpoints using Postman. In this project, we focus to create the models required to implement CRUD operations in the reimplementation-back-end repository and test the endpoints using Swagger API.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
#rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
#RAILS_ENV=test rails rswag &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionnairesController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_spec_new.png|border|800px|]]  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Questionnaire_swagger.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionsController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_spec_new.png|border|800px|]] &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Question_Swagger.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
#rspec spec/models/question_spec.rb&lt;br /&gt;
&lt;br /&gt;
'''Tests for Questionnaire model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_model_test.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for Question model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_model_test.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
*The questions and questionnaires model in the reimplementation-back-end repo has been updated to have question_type and questionnaire_type attribute instead of type attribute. Ruby has implicit inheritance when the type attribute is used. However, our repo does not have the dependent models for each type of Question and Questionnaire. For future implementation, those model classes could be added and this attribute can be refactored in the model and controller files.&lt;br /&gt;
*Implement other associations (for example: assignments) within each models.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:''' https://youtu.be/zkId16tklXI&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150313</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150313"/>
		<updated>2023-05-01T00:36:16Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
The current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&amp;lt;br&amp;gt;&lt;br /&gt;
To get the QuestionnairesController and QuestionsController endpoints running in the reimplementation-back-end repository, we need to reimplement the respective model files and add other dependent files.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following UML diagram shows the association between models we will be working on -&lt;br /&gt;
&lt;br /&gt;
[[File:oodd_uml.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
Below is the implementation plan that we have followed for E2345:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Implement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the instructor_id with the instructor details within the questionnaire object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questionnaires = Questionnaire.order(:id)&lt;br /&gt;
    render json: @questionnaires, status: :ok and return&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire. Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire if it exists, otherwise provides with appropriate error. It should delete the questionnaire only if there are no questions associated to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.delete&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # Save questionnaire information&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.update(questionnaire_params)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def copy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.copy_questionnaire_details(params)&lt;br /&gt;
      render json: &amp;quot;Copy of the questionnaire has been created successfully.&amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*toggle_access: This is a GET endpoint that changes the access from public to private and vice versa if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def toggle_access&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.private = !@questionnaire.private&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      @access = @questionnaire.private == true ? 'private' : 'public'&lt;br /&gt;
      render json: &amp;quot;The questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been successfully made #{@access}. &amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questions = Question.order(:id)&lt;br /&gt;
    render json: @questions, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      render json: @question, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the question parameters and creates a new question. Refactor the Create endpoint in questions_controller.rb such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a question ID and deletes that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.destroy&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*delete_all: This is a DELETE endpoint that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*shiw_all: This is a GET endpoint that takes questionnaire_id as the path parameter and shows all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully displayed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def show_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questions = @questionnaire.questions&lt;br /&gt;
      render json: @questions, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.update(question_params)&lt;br /&gt;
      @question.save!&lt;br /&gt;
      render json: @question, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def types&lt;br /&gt;
    types = Question.distinct.pluck(:question_type)&lt;br /&gt;
    render json: types.to_a, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
Rspec test skeleton for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could only do manual testing of our controller endpoints using Postman. In this project, we focus to create the models required to implement CRUD operations in the reimplementation-back-end repository and test the endpoints using Swagger API.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
#rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
#RAILS_ENV=test rails rswag &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionnairesController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_spec_new.jpeg|border|800px|]]  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Questionnaire_swagger.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionsController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_spec_new.jpeg|border|800px|]] &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Question_Swagger.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
#rspec spec/models/question_spec.rb&lt;br /&gt;
&lt;br /&gt;
'''Tests for Questionnaire model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_model_test.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for Question model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_model_test.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
*The questions and questionnaires model in the reimplementation-back-end repo has been updated to have question_type and questionnaire_type attribute instead of type attribute. Ruby has implicit inheritance when the type attribute is used. However, our repo does not have the dependent models for each type of Question and Questionnaire. For future implementation, those model classes could be added and this attribute can be refactored in the model and controller files.&lt;br /&gt;
*Implement other associations (for example: assignments) within each models.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:''' https://youtu.be/zkId16tklXI&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_spec_new.png&amp;diff=150312</id>
		<title>File:Question spec new.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_spec_new.png&amp;diff=150312"/>
		<updated>2023-05-01T00:35:11Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_spec_new.png&amp;diff=150311</id>
		<title>File:Questionnaire spec new.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_spec_new.png&amp;diff=150311"/>
		<updated>2023-05-01T00:34:57Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150310</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150310"/>
		<updated>2023-05-01T00:33:45Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
The current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&amp;lt;br&amp;gt;&lt;br /&gt;
To get the QuestionnairesController and QuestionsController endpoints running in the reimplementation-back-end repository, we need to reimplement the respective model files and add other dependent files.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following UML diagram shows the association between models we will be working on -&lt;br /&gt;
&lt;br /&gt;
[[File:oodd_uml.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
Below is the implementation plan that we have followed for E2345:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Implement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the instructor_id with the instructor details within the questionnaire object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questionnaires = Questionnaire.order(:id)&lt;br /&gt;
    render json: @questionnaires, status: :ok and return&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire. Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire if it exists, otherwise provides with appropriate error. It should delete the questionnaire only if there are no questions associated to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.delete&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # Save questionnaire information&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.update(questionnaire_params)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def copy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.copy_questionnaire_details(params)&lt;br /&gt;
      render json: &amp;quot;Copy of the questionnaire has been created successfully.&amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*toggle_access: This is a GET endpoint that changes the access from public to private and vice versa if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def toggle_access&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.private = !@questionnaire.private&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      @access = @questionnaire.private == true ? 'private' : 'public'&lt;br /&gt;
      render json: &amp;quot;The questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been successfully made #{@access}. &amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questions = Question.order(:id)&lt;br /&gt;
    render json: @questions, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      render json: @question, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the question parameters and creates a new question. Refactor the Create endpoint in questions_controller.rb such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a question ID and deletes that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.destroy&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*delete_all: This is a DELETE endpoint that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*shiw_all: This is a GET endpoint that takes questionnaire_id as the path parameter and shows all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully displayed.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def show_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questions = @questionnaire.questions&lt;br /&gt;
      render json: @questions, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.update(question_params)&lt;br /&gt;
      @question.save!&lt;br /&gt;
      render json: @question, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def types&lt;br /&gt;
    types = Question.distinct.pluck(:question_type)&lt;br /&gt;
    render json: types.to_a, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
Rspec test skeleton for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could only do manual testing of our controller endpoints using Postman. In this project, we focus to create the models required to implement CRUD operations in the reimplementation-back-end repository and test the endpoints using Swagger API.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
#rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
#RAILS_ENV=test rails rswag &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionnairesController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaires_controller_test.jpeg|border|800px|]]  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Questionnaire_swagger.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionsController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questions_controller_test.jpeg|border|800px|]] &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Question_Swagger.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
#rspec spec/models/question_spec.rb&lt;br /&gt;
&lt;br /&gt;
'''Tests for Questionnaire model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_model_test.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for Question model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_model_test.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
*The questions and questionnaires model in the reimplementation-back-end repo has been updated to have question_type and questionnaire_type attribute instead of type attribute. Ruby has implicit inheritance when the type attribute is used. However, our repo does not have the dependent models for each type of Question and Questionnaire. For future implementation, those model classes could be added and this attribute can be refactored in the model and controller files.&lt;br /&gt;
*Implement other associations (for example: assignments) within each models.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:''' https://youtu.be/zkId16tklXI&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150133</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=150133"/>
		<updated>2023-04-25T03:42:58Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
The current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&amp;lt;br&amp;gt;&lt;br /&gt;
To get the QuestionnairesController and QuestionsController endpoints running in the reimplementation-back-end repository, we need to reimplement the respective model files and add other dependent files.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following UML diagram shows the association between models we will be working on -&lt;br /&gt;
&lt;br /&gt;
[[File:oodd_uml.png|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
Below is the implementation plan that we have followed for E2345:&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Implement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the instructor_id with the instructor details within the questionnaire object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questionnaires = Questionnaire.order(:id)&lt;br /&gt;
    render json: @questionnaires, status: :ok and return&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire. Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire if it exists, otherwise provides with appropriate error. It should delete the questionnaire only if there are no questions associated to it.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.delete&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # Save questionnaire information&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.update(questionnaire_params)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def copy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.copy_questionnaire_details(params)&lt;br /&gt;
      render json: &amp;quot;Copy of the questionnaire has been created successfully.&amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*toggle_access: This is a GET endpoint that changes the access from public to private and vice versa if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def toggle_access&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.private = !@questionnaire.private&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      @access = @questionnaire.private == true ? 'private' : 'public'&lt;br /&gt;
      render json: &amp;quot;The questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been successfully made #{@access}. &amp;quot;, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def index&lt;br /&gt;
    @questions = Question.order(:id)&lt;br /&gt;
    render json: @questions, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def show&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      render json: @question, status: :ok&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*create: This is a POST endpoint that accepts the question parameters and creates a new question. Refactor the Create endpoint in questions_controller.rb such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*destroy: This is a DELETE endpoint that accepts a question ID and deletes that question if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.destroy&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*delete_all: This is a DELETE endpoint that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters if it exists, otherwise provides with appropriate error.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    begin&lt;br /&gt;
      @question = Question.find(params[:id])&lt;br /&gt;
      @question.update(question_params)&lt;br /&gt;
      @question.save!&lt;br /&gt;
      render json: @question, status: :ok and return&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def types&lt;br /&gt;
    types = Question.distinct.pluck(:question_type)&lt;br /&gt;
    render json: types.to_a, status: :ok&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
Rspec test skeleton for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could only do manual testing of our controller endpoints using Postman. In this project, we focus to create the models required to implement CRUD operations in the reimplementation-back-end repository and test the endpoints using Swagger API.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
#rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
#RAILS_ENV=test rails rswag &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionnairesController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaires_controller_test.jpeg|border|800px|]]  &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Questionnaire_swagger.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for QuestionsController:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questions_controller_test.jpeg|border|800px|]] &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Question_Swagger.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
#git clone &lt;br /&gt;
#cd reimplementation-back-end/&lt;br /&gt;
#bundle install&lt;br /&gt;
#rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
#rspec spec/models/question_spec.rb&lt;br /&gt;
&lt;br /&gt;
'''Tests for Questionnaire model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Questionnaire_model_test.jpeg|border|800px|]] &lt;br /&gt;
&lt;br /&gt;
'''Tests for Question model:''' [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File:Question_model_test.jpeg|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
== Future Work ==&lt;br /&gt;
*The questions and questionnaires model in the reimplementation-back-end repo has been updated to have question_type and questionnaire_type attribute instead of type attribute. Ruby has implicit inheritance when the type attribute is used. However, our repo does not have the dependent models for each type of Question and Questionnaire. For future implementation, those model classes could be added and this attribute can be refactored in the model and controller files.&lt;br /&gt;
*Implement other associations (for example: assignments) within each models.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:''' https://youtu.be/zkId16tklXI&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_Swagger.jpeg&amp;diff=149965</id>
		<title>File:Question Swagger.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_Swagger.jpeg&amp;diff=149965"/>
		<updated>2023-04-24T03:42:24Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_swagger.jpeg&amp;diff=149964</id>
		<title>File:Questionnaire swagger.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_swagger.jpeg&amp;diff=149964"/>
		<updated>2023-04-24T03:42:10Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaires_controller_test.jpeg&amp;diff=149961</id>
		<title>File:Questionnaires controller test.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaires_controller_test.jpeg&amp;diff=149961"/>
		<updated>2023-04-24T03:36:42Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Questions_controller_test.jpeg&amp;diff=149960</id>
		<title>File:Questions controller test.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Questions_controller_test.jpeg&amp;diff=149960"/>
		<updated>2023-04-24T03:18:51Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_model_test.jpeg&amp;diff=149954</id>
		<title>File:Question model test.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Question_model_test.jpeg&amp;diff=149954"/>
		<updated>2023-04-24T03:10:21Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_model_test.jpeg&amp;diff=149953</id>
		<title>File:Questionnaire model test.jpeg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Questionnaire_model_test.jpeg&amp;diff=149953"/>
		<updated>2023-04-24T03:10:09Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149937</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149937"/>
		<updated>2023-04-24T02:33:05Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Controller Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questions_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      # question = Object.const_get(params[:question][:type])&lt;br /&gt;
.create(txt: '', questionnaire_id: questionnaire_id, seq: num_of_existed_questions + 1, question_type:params[:question][:type], break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Create delete_all endpoint in QuestionsController that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor questionnaire_params and create sanitize_display_type to make the create and update endpoints more modular.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def questionnaire_params&lt;br /&gt;
    params.require(:questionnaire).permit(:name, :questionnaire_type, :private, :min_question_score, :max_question_score, :instructor_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def sanitize_display_type(type)&lt;br /&gt;
    display_type = type.split('Questionnaire')[0]&lt;br /&gt;
    if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
      display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
    end&lt;br /&gt;
    display_type&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor ''questionnaires_controller.rb'' and ''questions_controller.rb'' to handle ActiveRecord Errors and provide respective response codes. Handle response codes 200 (201 for create, 204 for delete) for successful execution, response code 404 for object not found, and 422 for unprocessable entity.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec:''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Unit tests for Question model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/question_spec.rb question_spec.rb]&lt;br /&gt;
:*Unit tests for Questionnaire model: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/models/questionnaire_spec.rb questionnaire_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.''' Kindly refer to the Testing Methodology section for detailed description.&lt;br /&gt;
:*Swagger tests for QuestionsController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb questions_spec.rb]&lt;br /&gt;
:*Swagger tests for QuestionnairesController: [https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb questionnaires_spec.rb]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a new Question with non-existing Questionnaire id in the database&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questions in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update the Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Question with the non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Question with existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Question with non-existing id in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 12|| Test to get a types of Questions present in the database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to delete all Questions of a Questionnaire with a valid Questionnaire id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to delete all Questions of a Questionnaire with an invalid Questionnaire id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.178.189:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.178.189:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.178.189:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.178.189:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149931</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149931"/>
		<updated>2023-04-24T02:24:26Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Controller Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
The current implementation of the Controllers include only manual testing via Postman. In E2345, we plan to add automated RSpec tests using the Swagger API to test each endpoint.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questions_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      # question = Object.const_get(params[:question][:type])&lt;br /&gt;
.create(txt: '', questionnaire_id: questionnaire_id, seq: num_of_existed_questions + 1, question_type:params[:question][:type], break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Create delete_all endpoint in QuestionsController that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor questionnaire_params and create sanitize_display_type to make the create and update endpoints more modular.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def questionnaire_params&lt;br /&gt;
    params.require(:questionnaire).permit(:name, :questionnaire_type, :private, :min_question_score, :max_question_score, :instructor_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def sanitize_display_type(type)&lt;br /&gt;
    display_type = type.split('Questionnaire')[0]&lt;br /&gt;
    if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
      display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
    end&lt;br /&gt;
    display_type&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor ''questionnaires_controller.rb'' and ''questions_controller.rb'' to handle ActiveRecord Errors and provide respective response codes. Handle response codes 200 (201 for create, 204 for delete) for successful execution, response code 404 for object not found, and 422 for unprocessable entity.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec.'''&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.'''&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with non-existing id in database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.178.189:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.178.189:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.178.189:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.178.189:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149930</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149930"/>
		<updated>2023-04-24T02:22:24Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
The current implementation of the Controllers include only manual testing via Postman. In E2345, we plan to add automated RSpec tests using the Swagger API to test each endpoint.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321.'''&amp;lt;br&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questions_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      # question = Object.const_get(params[:question][:type])&lt;br /&gt;
.create(txt: '', questionnaire_id: questionnaire_id, seq: num_of_existed_questions + 1, question_type:params[:question][:type], break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Create delete_all endpoint in QuestionsController that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor questionnaire_params and create sanitize_display_type to make the create and update endpoints more modular.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def questionnaire_params&lt;br /&gt;
    params.require(:questionnaire).permit(:name, :questionnaire_type, :private, :min_question_score, :max_question_score, :instructor_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def sanitize_display_type(type)&lt;br /&gt;
    display_type = type.split('Questionnaire')[0]&lt;br /&gt;
    if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
      display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
    end&lt;br /&gt;
    display_type&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor ''questionnaires_controller.rb'' and ''questions_controller.rb'' to handle ActiveRecord Errors and provide respective response codes. Handle response codes 200 (201 for create, 204 for delete) for successful execution, response code 404 for object not found, and 422 for unprocessable entity.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write unit tests for Questions model and Questionnaires model using Rspec.'''&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
'''Write Rspec tests using Swagger API for each endpoint of QuestionsController and QuestionnairesController.'''&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire with existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to create a copy of Questionnaire with non-existing id in database.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update a Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to update a Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to update a Questionnaire with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to delete Questionnaire with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to delete Questionnaire with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to show a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to show a Questionnaire with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test to toggle private boolean flag of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test to toggle private boolean flag of a Questionnaire with a invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.178.189:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.178.189:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.178.189:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.178.189:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149926</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149926"/>
		<updated>2023-04-24T02:16:14Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
The current implementation of the Controllers include only manual testing via Postman. In E2345, we plan to add automated RSpec tests using the Swagger API to test each endpoint.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questions_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      # question = Object.const_get(params[:question][:type])&lt;br /&gt;
.create(txt: '', questionnaire_id: questionnaire_id, seq: num_of_existed_questions + 1, question_type:params[:question][:type], break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Create delete_all endpoint in QuestionsController that takes questionnaire_id as the path parameter and deletes all questions associated to that questionnaire. It returns status 404 if the questionnaire does not exist, status 422 if no questions are associated to that questionnaire and status 200 if all the questions are successfully deleted.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      if @questionnaire.questions.size &amp;gt; 0 &lt;br /&gt;
        @questionnaire.questions.destroy_all&lt;br /&gt;
        msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
        render json: msg, status: :ok&lt;br /&gt;
      else&lt;br /&gt;
        render json: &amp;quot;No questions associated to Questionnaire ID:&amp;quot; + params[:id].to_s, status: :unprocessable_entity and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor questionnaire_params and create sanitize_display_type to make the create and update endpoints more modular.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def questionnaire_params&lt;br /&gt;
    params.require(:questionnaire).permit(:name, :questionnaire_type, :private, :min_question_score, :max_question_score, :instructor_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def sanitize_display_type(type)&lt;br /&gt;
    display_type = type.split('Questionnaire')[0]&lt;br /&gt;
    if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
      display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
    end&lt;br /&gt;
    display_type&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Questionnaire with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Questionnaire with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Questionnaire with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to toggle private boolean flag of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to toggle private boolean flag of a Questionnaire with a invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test ensures minimum score is smaller than maximum score.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test ensures minimum score is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test validates the association that a questionnaire comprises of several questions.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test ensures that a questionnaire is not deleted when it has questions associated.&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Test ensures calls from the method copy_questionnaire_details.&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Test ensures creation of a copy of given questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Test ensures creation of copy of all the present questionnaire in the database.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.178.189:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.178.189:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.178.189:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.178.189:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149922</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149922"/>
		<updated>2023-04-24T02:04:50Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Model Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
The current implementation of the Controllers include only manual testing via Postman. In E2345, we plan to add automated RSpec tests using the Swagger API to test each endpoint.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: &lt;br /&gt;
                                      { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questions_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Question object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      # question = Object.const_get(params[:question][:type])&lt;br /&gt;
.create(txt: '', questionnaire_id: questionnaire_id, seq: num_of_existed_questions + 1, question_type:params[:question][:type], break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Questionnaire with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Questionnaire with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Questionnaire with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to toggle private boolean flag of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to toggle private boolean flag of a Questionnaire with a invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field.&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test validates the name of the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test validates the instructor id in the questionnaire .&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test validates the maximum score in the questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures maximum score of the questionnaire is an integer.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test ensures maximum score is positive.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test ensures maximum score is greater than the minimum score.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test validates minimum score of a questionnaire.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.178.189:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.178.189:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.178.189:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.178.189:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149919</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149919"/>
		<updated>2023-04-24T02:00:49Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Model Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
The current implementation of the Controllers include only manual testing via Postman. In E2345, we plan to add automated RSpec tests using the Swagger API to test each endpoint.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, the as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
In the above code, &lt;br /&gt;
::*The as_json method is used to decorate the JSON object that is returned as a part of the response body from the controller endpoint. It is used to replace the questionnaire_id with the questionnaire details within the question object in JSON format.&lt;br /&gt;
::*The check_for_question_associations method is used to raise an Error if a Questionnaire that has associated questions is tried to be deleted. &lt;br /&gt;
::*The copy_questionnaire_details method is used to create a new object with the same attributes of the questionnaire and save it to the database. It is called when the copy endpoint is requested.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.new(questionnaire_params)&lt;br /&gt;
      @questionnaire.display_type = sanitize_display_type(@questionnaire.questionnaire_type)&lt;br /&gt;
      @questionnaire.save!&lt;br /&gt;
      render json: @questionnaire, status: :created and return&lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Refactor the Create endpoint in ''questions_controller.rb'' such that individual fields does not need to be set and validated. The below code represents the revised implementation of the method. A Questionnaire object is created using the new method instead of manual assignment of attributes.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def create&lt;br /&gt;
    begin&lt;br /&gt;
      questionnaire_id = params[:questionnaire_id] unless params[:questionnaire_id].nil?&lt;br /&gt;
      num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
      question = Question.create(&lt;br /&gt;
        txt: params[:txt],&lt;br /&gt;
        questionnaire_id: questionnaire_id,&lt;br /&gt;
        seq: num_of_existed_questions + 1,&lt;br /&gt;
        question_type: params[:question_type],&lt;br /&gt;
        break_before: true)&lt;br /&gt;
      # question = Object.const_get(params[:question][:type]).create(txt: '', questionnaire_id: questionnaire_id, seq: num_of_existed_questions + 1, question_type: params[:question][:type], break_before: true)&lt;br /&gt;
      case question.question_type&lt;br /&gt;
        when 'Scale'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
        when 'Cake', 'Criterion'&lt;br /&gt;
          question.weight = params[:weight]&lt;br /&gt;
          question.max_label = 'Strongly agree'&lt;br /&gt;
          question.min_label = 'Strongly disagree'&lt;br /&gt;
          question.size = '50, 3'&lt;br /&gt;
        when 'Dropdown'&lt;br /&gt;
          question.alternatives = '0|1|2|3|4|5'&lt;br /&gt;
          question.size = nil&lt;br /&gt;
        when 'TextArea'&lt;br /&gt;
          question.size = '60, 5'&lt;br /&gt;
        when 'TextField'&lt;br /&gt;
          question.size = '30'&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      question.save!&lt;br /&gt;
      render json: question, status: :created&lt;br /&gt;
    rescue ActiveRecord::RecordNotFound&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :not_found and return  &lt;br /&gt;
    rescue ActiveRecord::RecordInvalid&lt;br /&gt;
      render json: $ERROR_INFO.to_s, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
  # DELETE on /questions/delete_all/&amp;lt;questionnaire_id&amp;gt;&lt;br /&gt;
  # Endpoint to delete all questions associated to a particular questionnaire.&lt;br /&gt;
  def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.questions.destroy_all&lt;br /&gt;
      msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
      render json: msg, status: :ok&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
  # DELETE on /questionnaires/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      name = @questionnaire.name&lt;br /&gt;
      questions = @questionnaire.questions&lt;br /&gt;
      # questions.each do |question|&lt;br /&gt;
      #   question.delete&lt;br /&gt;
      # end&lt;br /&gt;
      unless questions.nil?&lt;br /&gt;
        msg = &amp;quot;This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: &amp;quot;&lt;br /&gt;
        link = &amp;quot;/questions/delete_all/&amp;quot; + @questionnaire.id.to_s&lt;br /&gt;
        msg += link&lt;br /&gt;
        render json: msg and return&lt;br /&gt;
      else&lt;br /&gt;
        @questionnaire.delete&lt;br /&gt;
        render json: &amp;quot;The questionnaire \&amp;quot;#{name}\&amp;quot; has been successfully deleted.&amp;quot;, status: :ok and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: e.message, status: :unprocessable_entity and return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Questionnaire with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Questionnaire with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Questionnaire with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to toggle private boolean flag of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to toggle private boolean flag of a Questionnaire with a invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question has valid attributes defined.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test ensures that a question is not valid without seq field.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test ensures that a question is not valid without txt field.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test ensures that a question is not valid without question_type field.&lt;br /&gt;
|-&lt;br /&gt;
|6|| Test ensures that a question is not valid without break_before field&lt;br /&gt;
|-&lt;br /&gt;
|7|| Test ensures that a question does not exist without a questionnaire&lt;br /&gt;
|-&lt;br /&gt;
|8|| Test ensures that a question object is deleted properly taking all its association into consideration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test that Questionnaire requires max_question_score and min_question_score to be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Questionnaire can have questions associated with it.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test that Questionnaire can have assignments associated with it through assignment_questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test that Questionnaire validates the questionnaire.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.178.189:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.178.189:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.178.189:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.178.189:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149916</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149916"/>
		<updated>2023-04-24T01:56:16Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Model Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
The current implementation of the Controllers include only manual testing via Postman. In E2345, we plan to add automated RSpec tests using the Swagger API to test each endpoint.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
  # POST on /questionnaires&lt;br /&gt;
  def create&lt;br /&gt;
    if params[:questionnaire][:name].blank?&lt;br /&gt;
      render json: &amp;quot;Questionnaire name cannot be blank.&amp;quot;, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      display_type = params[:questionnaire][:type].split('Questionnaire')[0]&lt;br /&gt;
      @questionnaire = Object.const_get(params[:questionnaire][:type]).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:questionnaire][:type]&lt;br /&gt;
      @questionnaire.private = params[:questionnaire][:private] == 'true'&lt;br /&gt;
      @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
      @questionnaire.instructor_id = 6 # 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;
      if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
        display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
      end&lt;br /&gt;
      @questionnaire.display_type = display_type&lt;br /&gt;
      @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
      @questionnaire.save&lt;br /&gt;
      render json: @questionnaire, status: :created&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = $ERROR_INFO&lt;br /&gt;
      render json: msg, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
  # DELETE on /questions/delete_all/&amp;lt;questionnaire_id&amp;gt;&lt;br /&gt;
  # Endpoint to delete all questions associated to a particular questionnaire.&lt;br /&gt;
  def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.questions.destroy_all&lt;br /&gt;
      msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
      render json: msg, status: :ok&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
  # DELETE on /questionnaires/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      name = @questionnaire.name&lt;br /&gt;
      questions = @questionnaire.questions&lt;br /&gt;
      # questions.each do |question|&lt;br /&gt;
      #   question.delete&lt;br /&gt;
      # end&lt;br /&gt;
      unless questions.nil?&lt;br /&gt;
        msg = &amp;quot;This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: &amp;quot;&lt;br /&gt;
        link = &amp;quot;/questions/delete_all/&amp;quot; + @questionnaire.id.to_s&lt;br /&gt;
        msg += link&lt;br /&gt;
        render json: msg and return&lt;br /&gt;
      else&lt;br /&gt;
        @questionnaire.delete&lt;br /&gt;
        render json: &amp;quot;The questionnaire \&amp;quot;#{name}\&amp;quot; has been successfully deleted.&amp;quot;, status: :ok and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: e.message, status: :unprocessable_entity and return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Questionnaire with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Questionnaire with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Questionnaire with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to toggle private boolean flag of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to toggle private boolean flag of a Questionnaire with a invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question belongs to a Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test that Question requires a sequence number.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test that Question requires a question type.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test that Question requires a break_before flag.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test that Questionnaire requires max_question_score and min_question_score to be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Questionnaire can have questions associated with it.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test that Questionnaire can have assignments associated with it through assignment_questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test that Questionnaire validates the questionnaire.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.178.189:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.178.189:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.178.189:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.178.189:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.178.189:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.178.189:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.178.189:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.178.189:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149915</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149915"/>
		<updated>2023-04-24T01:54:11Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Question and Questionnaire models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should written in the RSwag test format.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
The current implementation of the Controllers include only manual testing via Postman. In E2345, we plan to add automated RSpec tests using the Swagger API to test each endpoint.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
We did not have models for Questionnaires and Questions, along with other primary models on which the Questionnaire and Question model depend on in the reimplementation-back-end repository, so we ran it on expertiza repository. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add required associations for ''user.rb, role.rb, question.rb, and questionnaire.rb'' only.&lt;br /&gt;
:*The below code snippets represent current implementation of ''question.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Question &amp;lt; ApplicationRecord&lt;br /&gt;
    belongs_to :questionnaire # each question belongs to a specific questionnaire&lt;br /&gt;
    &lt;br /&gt;
    validates :seq, presence: true, numericality: true # sequence must be numeric&lt;br /&gt;
    validates :txt, length: { minimum: 0, allow_nil: false, message: &amp;quot;can't be nil&amp;quot; } # user must define text content for a question&lt;br /&gt;
    validates :question_type, presence: true # user must define type for a question&lt;br /&gt;
    validates :break_before, presence: true&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[questionnaire_id txt weight seq question_type size alternatives break_before min_label max_label created_at updated_at],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                questionnaire: { only: %i[name private min_question_score max_question_score instructor_id created_at updated_at questionnaire_type] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['questionnaire'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
:*The below code snippets represent current implementation of ''questionnaire.rb'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Questionnaire &amp;lt; ApplicationRecord&lt;br /&gt;
    has_many :questions, dependent: :restrict_with_error&lt;br /&gt;
    belongs_to :instructor&lt;br /&gt;
  &lt;br /&gt;
    before_destroy :check_for_question_associations&lt;br /&gt;
&lt;br /&gt;
    validate :validate_questionnaire&lt;br /&gt;
    validates :name, presence: true&lt;br /&gt;
    validates :max_question_score, :min_question_score, numericality: true&lt;br /&gt;
  &lt;br /&gt;
    # clones the contents of a questionnaire, including the questions and associated advice&lt;br /&gt;
    def self.copy_questionnaire_details(params)&lt;br /&gt;
      orig_questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      questions = Question.where(questionnaire_id: params[:id])&lt;br /&gt;
      questionnaire = orig_questionnaire.dup&lt;br /&gt;
      questionnaire.name = 'Copy of ' + orig_questionnaire.name&lt;br /&gt;
      questionnaire.created_at = Time.zone.now&lt;br /&gt;
      questionnaire.updated_at = Time.zone.now&lt;br /&gt;
      questionnaire.save!&lt;br /&gt;
      questions.each do |question|&lt;br /&gt;
        new_question = question.dup&lt;br /&gt;
        new_question.questionnaire_id = questionnaire.id&lt;br /&gt;
        new_question.save!&lt;br /&gt;
      end&lt;br /&gt;
      questionnaire&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    # validate the entries for this questionnaire&lt;br /&gt;
    def validate_questionnaire&lt;br /&gt;
      errors.add(:max_question_score, 'The maximum question score must be a positive integer.') if max_question_score &amp;lt; 1&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be a positive integer.') if min_question_score &amp;lt; 0&lt;br /&gt;
      errors.add(:min_question_score, 'The minimum question score must be less than the maximum.') if min_question_score &amp;gt;= max_question_score&lt;br /&gt;
      results = Questionnaire.where('id &amp;lt;&amp;gt; ? and name = ? and instructor_id = ?', id, name, instructor_id)&lt;br /&gt;
      errors.add(:name, 'Questionnaire names must be unique.') if results.present?&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    # Check_for_question_associations checks if questionnaire has associated questions or not&lt;br /&gt;
    def check_for_question_associations&lt;br /&gt;
      if questions.any?&lt;br /&gt;
        raise ActiveRecord::DeleteRestrictionError.new(:base, &amp;quot;Cannot delete record because dependent questions exist&amp;quot;)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def as_json(options = {})&lt;br /&gt;
        super(options.merge({&lt;br /&gt;
                              only: %i[id name private min_question_score max_question_score created_at updated_at questionnaire_type],&lt;br /&gt;
                              include: {&lt;br /&gt;
                                instructor: { only: %i[name email fullname password role] }&lt;br /&gt;
                              }&lt;br /&gt;
                            })).tap do |hash|&lt;br /&gt;
          hash['instructor'] ||= { id: nil, name: nil }&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
  # POST on /questionnaires&lt;br /&gt;
  def create&lt;br /&gt;
    if params[:questionnaire][:name].blank?&lt;br /&gt;
      render json: &amp;quot;Questionnaire name cannot be blank.&amp;quot;, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      display_type = params[:questionnaire][:type].split('Questionnaire')[0]&lt;br /&gt;
      @questionnaire = Object.const_get(params[:questionnaire][:type]).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:questionnaire][:type]&lt;br /&gt;
      @questionnaire.private = params[:questionnaire][:private] == 'true'&lt;br /&gt;
      @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
      @questionnaire.instructor_id = 6 # 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;
      if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
        display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
      end&lt;br /&gt;
      @questionnaire.display_type = display_type&lt;br /&gt;
      @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
      @questionnaire.save&lt;br /&gt;
      render json: @questionnaire, status: :created&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = $ERROR_INFO&lt;br /&gt;
      render json: msg, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
  # DELETE on /questions/delete_all/&amp;lt;questionnaire_id&amp;gt;&lt;br /&gt;
  # Endpoint to delete all questions associated to a particular questionnaire.&lt;br /&gt;
  def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.questions.destroy_all&lt;br /&gt;
      msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
      render json: msg, status: :ok&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
  # DELETE on /questionnaires/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      name = @questionnaire.name&lt;br /&gt;
      questions = @questionnaire.questions&lt;br /&gt;
      # questions.each do |question|&lt;br /&gt;
      #   question.delete&lt;br /&gt;
      # end&lt;br /&gt;
      unless questions.nil?&lt;br /&gt;
        msg = &amp;quot;This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: &amp;quot;&lt;br /&gt;
        link = &amp;quot;/questions/delete_all/&amp;quot; + @questionnaire.id.to_s&lt;br /&gt;
        msg += link&lt;br /&gt;
        render json: msg and return&lt;br /&gt;
      else&lt;br /&gt;
        @questionnaire.delete&lt;br /&gt;
        render json: &amp;quot;The questionnaire \&amp;quot;#{name}\&amp;quot; has been successfully deleted.&amp;quot;, status: :ok and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: e.message, status: :unprocessable_entity and return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Questionnaire with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Questionnaire with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Questionnaire with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to toggle private boolean flag of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to toggle private boolean flag of a Questionnaire with a invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
&lt;br /&gt;
====Model Tests====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To run the model tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/models/question_spec.rb&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Question belongs to a Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test that Question requires a sequence number.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Question sequence number must be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test that Question requires a question type.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test that Question requires a break_before flag.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
5. bundle exec rspec spec/models/questionnaire_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test that Questionnaire requires a name.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test that Questionnaire requires max_question_score and min_question_score to be numerical.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test that Questionnaire can have questions associated with it.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test that Questionnaire can have assignments associated with it through assignment_questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test that Questionnaire validates the questionnaire.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.177.152:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.177.152:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.177.152:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.177.152:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.177.152:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.177.152:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.177.152:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.177.152:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.177.152:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.177.152:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.177.152:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.178.189:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=User:Vchheda&amp;diff=149904</id>
		<title>User:Vchheda</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=User:Vchheda&amp;diff=149904"/>
		<updated>2023-04-24T01:25:53Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149573</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149573"/>
		<updated>2023-04-12T23:55:52Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depend on in the reimplementation back-end repository, so we ran it on expertise repository. Also, current available test were using the Postman tool. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
[[File:UML_diagram_2345.png|center|border|800px|]]&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
  # POST on /questionnaires&lt;br /&gt;
  def create&lt;br /&gt;
    if params[:questionnaire][:name].blank?&lt;br /&gt;
      render json: &amp;quot;Questionnaire name cannot be blank.&amp;quot;, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      display_type = params[:questionnaire][:type].split('Questionnaire')[0]&lt;br /&gt;
      @questionnaire = Object.const_get(params[:questionnaire][:type]).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:questionnaire][:type]&lt;br /&gt;
      @questionnaire.private = params[:questionnaire][:private] == 'true'&lt;br /&gt;
      @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
      @questionnaire.instructor_id = 6 # 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;
      if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
        display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
      end&lt;br /&gt;
      @questionnaire.display_type = display_type&lt;br /&gt;
      @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
      @questionnaire.save&lt;br /&gt;
      render json: @questionnaire, status: :created&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = $ERROR_INFO&lt;br /&gt;
      render json: msg, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
  # DELETE on /questions/delete_all/&amp;lt;questionnaire_id&amp;gt;&lt;br /&gt;
  # Endpoint to delete all questions associated to a particular questionnaire.&lt;br /&gt;
  def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.questions.destroy_all&lt;br /&gt;
      msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
      render json: msg, status: :ok&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
  # DELETE on /questionnaires/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      name = @questionnaire.name&lt;br /&gt;
      questions = @questionnaire.questions&lt;br /&gt;
      # questions.each do |question|&lt;br /&gt;
      #   question.delete&lt;br /&gt;
      # end&lt;br /&gt;
      unless questions.nil?&lt;br /&gt;
        msg = &amp;quot;This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: &amp;quot;&lt;br /&gt;
        link = &amp;quot;/questions/delete_all/&amp;quot; + @questionnaire.id.to_s&lt;br /&gt;
        msg += link&lt;br /&gt;
        render json: msg and return&lt;br /&gt;
      else&lt;br /&gt;
        @questionnaire.delete&lt;br /&gt;
        render json: &amp;quot;The questionnaire \&amp;quot;#{name}\&amp;quot; has been successfully deleted.&amp;quot;, status: :ok and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: e.message, status: :unprocessable_entity and return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
&lt;br /&gt;
====Controller Tests====&lt;br /&gt;
&lt;br /&gt;
To run the controller tests:&lt;br /&gt;
&lt;br /&gt;
1. git clone &lt;br /&gt;
&lt;br /&gt;
2. cd reimplementation-back-end/&lt;br /&gt;
&lt;br /&gt;
3. bundle install&lt;br /&gt;
&lt;br /&gt;
4. bundle exec rspec spec/requests/api/v1/questionnaires_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Questionnaire with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Questionnaire with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to create a copy of Questionnaire.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to list the Questionnaires.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Questionnaire with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to update the Questionnaire with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Questionnaire with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to delete Questionnaire with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Test to show a Questionnaire with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Test to toggle private boolean flag of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Test to toggle private boolean flag of a Questionnaire with a invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
bundle exec rspec spec/requests/api/v1/questions_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left:30px&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr No !! Test Description &lt;br /&gt;
|-&lt;br /&gt;
| 1 || Test to create a new Question with valid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Test to create a new Question with invalid parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Test to list the Questions.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Test to update the Question with correct parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Test to update the Question with incorrect parameters.&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Test to delete Question with existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Test to delete Question with the non-existing id.&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Test to show a Question with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Test to show a Question with an invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|10|| Test to get a type of a Question with valid id.&lt;br /&gt;
|-&lt;br /&gt;
|11|| Test to get a type of a Question with invalid id.&lt;br /&gt;
|-&lt;br /&gt;
|12|| Test to delete all Questions of a Questionnaire with a valid id.&lt;br /&gt;
|-&lt;br /&gt;
|13|| Test to delete all Questions of a Questionnaire with an invalid id.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman. Given below are the endpoints which we tested successfully on Postman. &lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.177.152:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.177.152:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.177.152:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.177.152:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
'''Questions Controller'''&lt;br /&gt;
#index: GET method - http://152.7.177.152:8080/api/v1/questions/&lt;br /&gt;
#show: GET method - http://152.7.177.152:8080/api/v1/questions/1&lt;br /&gt;
#create: POST method - http://152.7.177.152:8080/api/v1/questions/&lt;br /&gt;
#destroy: DELETE method - http://152.7.177.152:8080/api/v1/questions/2&lt;br /&gt;
#update: PUT method - http://152.7.177.152:8080/api/v1/questions/2&lt;br /&gt;
#delete all: DELETE method - http://152.7.177.152:8080/api/v1/questions/delete_all/2&lt;br /&gt;
#types: GET method - http://152.7.177.152:8080/api/v1/questions/types&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.177.152:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149553</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149553"/>
		<updated>2023-04-12T23:24:46Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Relevant Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depend on in the reimplementation back-end repository, so we ran it on expertise repository. Also, current available test were using the Postman tool. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
[[File:UML_diagram_2345.png|center|border|800px|]]&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
  # POST on /questionnaires&lt;br /&gt;
  def create&lt;br /&gt;
    if params[:questionnaire][:name].blank?&lt;br /&gt;
      render json: &amp;quot;Questionnaire name cannot be blank.&amp;quot;, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      display_type = params[:questionnaire][:type].split('Questionnaire')[0]&lt;br /&gt;
      @questionnaire = Object.const_get(params[:questionnaire][:type]).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:questionnaire][:type]&lt;br /&gt;
      @questionnaire.private = params[:questionnaire][:private] == 'true'&lt;br /&gt;
      @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
      @questionnaire.instructor_id = 6 # 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;
      if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
        display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
      end&lt;br /&gt;
      @questionnaire.display_type = display_type&lt;br /&gt;
      @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
      @questionnaire.save&lt;br /&gt;
      render json: @questionnaire, status: :created&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = $ERROR_INFO&lt;br /&gt;
      render json: msg, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
  # DELETE on /questions/delete_all/&amp;lt;questionnaire_id&amp;gt;&lt;br /&gt;
  # Endpoint to delete all questions associated to a particular questionnaire.&lt;br /&gt;
  def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.questions.destroy_all&lt;br /&gt;
      msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
      render json: msg, status: :ok&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
  # DELETE on /questionnaires/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      name = @questionnaire.name&lt;br /&gt;
      questions = @questionnaire.questions&lt;br /&gt;
      # questions.each do |question|&lt;br /&gt;
      #   question.delete&lt;br /&gt;
      # end&lt;br /&gt;
      unless questions.nil?&lt;br /&gt;
        msg = &amp;quot;This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: &amp;quot;&lt;br /&gt;
        link = &amp;quot;/questions/delete_all/&amp;quot; + @questionnaire.id.to_s&lt;br /&gt;
        msg += link&lt;br /&gt;
        render json: msg and return&lt;br /&gt;
      else&lt;br /&gt;
        @questionnaire.delete&lt;br /&gt;
        render json: &amp;quot;The questionnaire \&amp;quot;#{name}\&amp;quot; has been successfully deleted.&amp;quot;, status: :ok and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: e.message, status: :unprocessable_entity and return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.177.152:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.177.152:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.177.152:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.177.152:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.177.152:8080&lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149552</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149552"/>
		<updated>2023-04-12T23:24:19Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depend on in the reimplementation back-end repository, so we ran it on expertise repository. Also, current available test were using the Postman tool. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
[[File:UML_diagram_2345.png|center|border|800px|]]&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
  # POST on /questionnaires&lt;br /&gt;
  def create&lt;br /&gt;
    if params[:questionnaire][:name].blank?&lt;br /&gt;
      render json: &amp;quot;Questionnaire name cannot be blank.&amp;quot;, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      display_type = params[:questionnaire][:type].split('Questionnaire')[0]&lt;br /&gt;
      @questionnaire = Object.const_get(params[:questionnaire][:type]).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:questionnaire][:type]&lt;br /&gt;
      @questionnaire.private = params[:questionnaire][:private] == 'true'&lt;br /&gt;
      @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
      @questionnaire.instructor_id = 6 # 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;
      if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
        display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
      end&lt;br /&gt;
      @questionnaire.display_type = display_type&lt;br /&gt;
      @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
      @questionnaire.save&lt;br /&gt;
      render json: @questionnaire, status: :created&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = $ERROR_INFO&lt;br /&gt;
      render json: msg, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
  # DELETE on /questions/delete_all/&amp;lt;questionnaire_id&amp;gt;&lt;br /&gt;
  # Endpoint to delete all questions associated to a particular questionnaire.&lt;br /&gt;
  def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.questions.destroy_all&lt;br /&gt;
      msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
      render json: msg, status: :ok&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
  # DELETE on /questionnaires/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      name = @questionnaire.name&lt;br /&gt;
      questions = @questionnaire.questions&lt;br /&gt;
      # questions.each do |question|&lt;br /&gt;
      #   question.delete&lt;br /&gt;
      # end&lt;br /&gt;
      unless questions.nil?&lt;br /&gt;
        msg = &amp;quot;This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: &amp;quot;&lt;br /&gt;
        link = &amp;quot;/questions/delete_all/&amp;quot; + @questionnaire.id.to_s&lt;br /&gt;
        msg += link&lt;br /&gt;
        render json: msg and return&lt;br /&gt;
      else&lt;br /&gt;
        @questionnaire.delete&lt;br /&gt;
        render json: &amp;quot;The questionnaire \&amp;quot;#{name}\&amp;quot; has been successfully deleted.&amp;quot;, status: :ok and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: e.message, status: :unprocessable_entity and return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.177.152:8080/api/v1/questionnaires&lt;br /&gt;
#show: GET method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#create: POST method - http://152.7.177.152:8080/api/v1/questionnaires/&lt;br /&gt;
#destroy: DELETE method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#update: .PUT method - http://152.7.177.152:8080/api/v1/questionnaires/1&lt;br /&gt;
#copy: POST method - http://152.7.177.152:8080/api/v1/questionnaires/copy/1&lt;br /&gt;
#toggle_access: GET method - http://152.7.177.152:8080/api/v1/questionnaires/toggle_access/1&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149551</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149551"/>
		<updated>2023-04-12T23:22:00Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depend on in the reimplementation back-end repository, so we ran it on expertise repository. Also, current available test were using the Postman tool. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
[[File:UML_diagram_2345.png|center|border|800px|]]&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
  # POST on /questionnaires&lt;br /&gt;
  def create&lt;br /&gt;
    if params[:questionnaire][:name].blank?&lt;br /&gt;
      render json: &amp;quot;Questionnaire name cannot be blank.&amp;quot;, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      display_type = params[:questionnaire][:type].split('Questionnaire')[0]&lt;br /&gt;
      @questionnaire = Object.const_get(params[:questionnaire][:type]).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:questionnaire][:type]&lt;br /&gt;
      @questionnaire.private = params[:questionnaire][:private] == 'true'&lt;br /&gt;
      @questionnaire.name = params[:questionnaire][:name]&lt;br /&gt;
      @questionnaire.instructor_id = 6 # 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;
      if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)&lt;br /&gt;
        display_type = (display_type.split(/(?=[A-Z])/)).join('%')&lt;br /&gt;
      end&lt;br /&gt;
      @questionnaire.display_type = display_type&lt;br /&gt;
      @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL&lt;br /&gt;
      @questionnaire.save&lt;br /&gt;
      render json: @questionnaire, status: :created&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      msg = $ERROR_INFO&lt;br /&gt;
      render json: msg, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
  # DELETE on /questions/delete_all/&amp;lt;questionnaire_id&amp;gt;&lt;br /&gt;
  # Endpoint to delete all questions associated to a particular questionnaire.&lt;br /&gt;
  def delete_all&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      @questionnaire.questions.destroy_all&lt;br /&gt;
      msg = &amp;quot;All questions for Questionnaire ID:&amp;quot; + params[:id].to_s + &amp;quot; has been successfully deleted!&amp;quot;&lt;br /&gt;
      render json: msg, status: :ok&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :unprocessable_entity&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
  # DELETE on /questionnaires/:id&lt;br /&gt;
  def destroy&lt;br /&gt;
    begin&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    rescue&lt;br /&gt;
      render json: $ERROR_INFO, status: :not_found and return&lt;br /&gt;
    end&lt;br /&gt;
    begin&lt;br /&gt;
      name = @questionnaire.name&lt;br /&gt;
      questions = @questionnaire.questions&lt;br /&gt;
      # questions.each do |question|&lt;br /&gt;
      #   question.delete&lt;br /&gt;
      # end&lt;br /&gt;
      unless questions.nil?&lt;br /&gt;
        msg = &amp;quot;This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: &amp;quot;&lt;br /&gt;
        link = &amp;quot;/questions/delete_all/&amp;quot; + @questionnaire.id.to_s&lt;br /&gt;
        msg += link&lt;br /&gt;
        render json: msg and return&lt;br /&gt;
      else&lt;br /&gt;
        @questionnaire.delete&lt;br /&gt;
        render json: &amp;quot;The questionnaire \&amp;quot;#{name}\&amp;quot; has been successfully deleted.&amp;quot;, status: :ok and return&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError =&amp;gt; e&lt;br /&gt;
      render json: e.message, status: :unprocessable_entity and return&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
'''Questionnaires Controller'''&lt;br /&gt;
#index: GET method - http://152.7.177.152:8080/api/v1/questionnaires&lt;br /&gt;
#show: &lt;br /&gt;
#create: &lt;br /&gt;
#destroy: &lt;br /&gt;
#update: .&lt;br /&gt;
#copy: &lt;br /&gt;
#toggle_access:&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149542</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149542"/>
		<updated>2023-04-12T23:01:29Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Current Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below. (Information related to separating responsibilities, bugs fixed, current testing and unused functionality can be found on the above link for plan of current implementation.)&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depend on in the reimplementation back-end repository, so we ran it on expertise repository. Also, current available test were using the Postman tool. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149536</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149536"/>
		<updated>2023-04-12T22:51:18Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Implementation Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below.&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depend on in the reimplementation back-end repository, so we ran it on expertise repository. Also, current available test were using the Postman tool. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149535</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149535"/>
		<updated>2023-04-12T22:50:42Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Implementation Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below.&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depended on in the reimplementation back-end repository, so we ran it on expertise repository. Also, current available test were using the Postman tool. To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149533</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149533"/>
		<updated>2023-04-12T22:49:16Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Implementation Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below.&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
We did not have models for Questionnaires and Questions controller model along with other primary models on which the Questionnaire and Question Controller model depended on.To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149530</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149530"/>
		<updated>2023-04-12T22:45:40Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Current Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed these responsibilities in the previous project:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below.&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149529</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149529"/>
		<updated>2023-04-12T22:44:43Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed this responsibilities:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below.&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149528</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149528"/>
		<updated>2023-04-12T22:44:01Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Current Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed this responsibilities:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
After seperation of the  responsibilities of the QuestionnairesController and QuestionsController, fixing bugs, discarding unused functionality, we reimplemented the code to create basic CRUD operations. Then the methods were converted to basic CRUD operations which are described below.&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
[[File:Q1.png|center|border|800px|]]&lt;br /&gt;
[[File:Q2.png|center|border|800px|]]&lt;br /&gt;
[[File:Q30.png|center|border|800px|]]&lt;br /&gt;
[[File:Q4.png|center|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
[[File:Q50.png|center|border|800px|]]&lt;br /&gt;
[[File:Q6.png|center|border|800px|]]&lt;br /&gt;
[[File:Q7.png|center|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149527</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149527"/>
		<updated>2023-04-12T22:40:37Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Current Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
We completed this responsibilities:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149525</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149525"/>
		<updated>2023-04-12T22:38:41Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Current Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
Plan for current implementation for the code can be found here [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321].&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149522</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149522"/>
		<updated>2023-04-12T22:36:32Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Current Implementation==&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149431</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149431"/>
		<updated>2023-04-12T13:49:24Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project [https://expertiza.csc.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController E2321] but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.&lt;br /&gt;
In our previous project we implemented the CRUD endpoints but since all the models were not present in reimplementation backend repository, we could not test our controller tests. In this project, we focus to create the models required to implement CRUD operations in the reimplementation backend repository and then run and test the API tests for the CRUD operations.&lt;br /&gt;
* Rspec unit and functional tests for Questionnaire and Question model will be created. (Since, we are implementing required models for reimplementation backend repository in this project, we plan to write unit and functional tests to test the methods written in the model.)&lt;br /&gt;
* Demonstrating working of API endpoints on Postman.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023&amp;diff=149345</id>
		<title>CSC/ECE 517 Spring 2023</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023&amp;diff=149345"/>
		<updated>2023-04-08T19:31:54Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* OSS Projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OSS Projects ==&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 -E2306. Refactor user_controller.rb, user.rb and its child classes]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2320. Reimplement the Question hierarchy]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2312 + E2313. Reimplement response.rb and responses_controller.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - NTNX-1. Support provisioning MongoDb via NDB Kubernetes Operator]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2316. Reimplement sign_up_sheet_controller.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2315. Reimplement signed_up_team.rb, sign_up_topic.rb, sign_up_sheet.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2340. Reimplement signed_up_team.rb, sign_up_topic.rb, sign_up_sheet.rb (Project 4)]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2323. Refactor DueDate functionality from assignment.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2317: Reimplement participant.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2314. Reimplement the response map hierarchy]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023- NTNX-4. Extend NDB operator provision postregresql aws]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2321. Reimplement QuestionnairesController and QuestionsController]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2305. Grading audit trail]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2329. Grading audit trail(Project 4)]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2309. Refactor Node model and its subclasses]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2300. Refactor E1858. Github metrics integration]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Sping 2023 - E2322: Refactor Questionnaire View to display Bookmark Rating]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - NTNX-3. Refactor models to keep profiles (software, compute, network, etc) as optional and use default if not specified]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023_-_E2301._Refactor_review_maping_helper]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023_-_E2330._Reimplementation_Invitation_Controller]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023_-_E2337._Reimplement_node_hierarchy]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023_-E2339._Reimplement signed_up_teams_controller and sign_up_topics_controller.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023_-_E2320._Reimplement the Question Hierarchy]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023 - E2341. UI for Participants.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023_-_E2336._Reimplement_response.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController]]&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149003</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=149003"/>
		<updated>2023-04-07T18:34:16Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: /* Testing Methodology */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* Ensure that the each of the models and controllers have loose coupling and tight cohesion.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Implementation Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
&lt;br /&gt;
* Rspec tests for Questionnaires Controller and Questions Controller&lt;br /&gt;
* Rspec tests for Questionnaire and Question model created to run the CRUD operations&lt;br /&gt;
* Demonstrating working of API endpoints on Postman&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=148947</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=148947"/>
		<updated>2023-04-07T03:06:06Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused functionality:&amp;lt;/b&amp;gt; Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
==General Design Goals==&lt;br /&gt;
* Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.&lt;br /&gt;
* DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.&lt;br /&gt;
* Ensure all present test cases still work properly after making the above changes and create additional test cases.&lt;br /&gt;
&lt;br /&gt;
==Action Plan==&lt;br /&gt;
To get the questions and questionnaires module running in the reimplementation-back-end repository, we plan to follow these steps:&amp;lt;br&amp;gt;&lt;br /&gt;
1. Reimplement basic version of ''question.rb'' and ''questionnaire.rb'' such that it facilitates the controllers' CRUD operations.&amp;lt;br&amp;gt;&lt;br /&gt;
:*Add associations to ''user.rb, role.rb, assignment.rb'' only.&lt;br /&gt;
:*Implement only the functions that depend on the above classes.&lt;br /&gt;
2. Write comprehensive test cases for both models using RSpec.&amp;lt;br&amp;gt;&lt;br /&gt;
3. Reimplement ''questions_controller.rb'' and ''questionnaires_controller.rb'' to incorporate the feedback received in E2321. The feedback is as follows:&amp;lt;br&amp;gt;&lt;br /&gt;
:*Optimize the Create method in ''questionnaires_controller.rb'' such that individual fields does not need to be set and validated.&lt;br /&gt;
:*Implement an endpoint to delete all questions associated with a questionnaire.&lt;br /&gt;
:*Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.&amp;lt;br&amp;gt;&lt;br /&gt;
4. Write comprehensive test cases for both controllers using RSpec.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' &lt;br /&gt;
* '''Test Video Link:'''&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=148748</id>
		<title>CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2345._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=148748"/>
		<updated>2023-04-05T02:48:34Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
This page gives a description of the changes made for the ''questions_controller.rb, questionnaire_controller.rb, question.rb &amp;amp; questionnaire.rb'' of Expertiza based OSS project.&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
&amp;lt;b&amp;gt;What is needed:&amp;lt;/b&amp;gt; This project builds on E2321, and the main goal is to get the endpoints of QuestionsController and QuestionnairesController running in reimplementation-backend repository. Detailed goals of the project are as follows:&lt;br /&gt;
#&amp;lt;b&amp;gt;Improving the clarity and conciseness of code:&amp;lt;/b&amp;gt; The code should be written in a clean and concise manner. Methods with identical names that perform different functionalities should be renamed for clarity. Functions or functionality that are not clear should be commented on or removed. Any loops or methods that can be refactored for better performance should be addressed.&lt;br /&gt;
#&amp;lt;b&amp;gt;Discarding unused or unclear functionality:&amp;lt;/b&amp;gt; Any unused or unclear functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two controllers:&amp;lt;/b&amp;gt; Tests should be written for both the QuestionnairesController and the QuestionsController. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
#&amp;lt;b&amp;gt;Reimplement Questions and Questionnaires models:&amp;lt;/b&amp;gt; Reimplement the two models to facilitate the endpoints of the respective controllers.&lt;br /&gt;
#&amp;lt;b&amp;gt;Writing tests for the two models:&amp;lt;/b&amp;gt; Tests should be written for both the Questionnaires and the Questions models. The tests should cover at least 80% of the code, and tools like Rubocop and Code Climate should be used to verify code smells.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.177.38:8080&lt;br /&gt;
* '''Test Video Link:''' https://bit.ly/E2321&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=148719</id>
		<title>CSC/ECE 517 Spring 2023 - E2321. Reimplement QuestionnairesController and QuestionsController</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_E2321._Reimplement_QuestionnairesController_and_QuestionsController&amp;diff=148719"/>
		<updated>2023-03-30T00:15:01Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''E2321. Reimplement QuestionnairesController and QuestionsController'''&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
The questionnaire is the superclass for all kinds of questionnaires and rubrics. Rubrics are used for evaluating submissions and teammate contributions, as well as taking quizzes and surveys, and all of these are subclasses of the Questionnaire class. In Expertiza, various types of questionnaires can be created, such as the Survey Questionnaire, Author Feedback Questionnaire, Bookmark Rating Questionnaire, Metareview Questionnaire, Quiz Questionnaire, Review Questionnaire, and Teammate Review Questionnaire. Each of these questionnaires can have zero or more questions, which are represented by the Question class. Typically, a questionnaire is associated with an assignment using the Assignment class.&lt;br /&gt;
&lt;br /&gt;
The Questionnaire Controller is responsible for performing CRUD (Create, Read, Update, Delete) operations, such as copying and viewing questionnaires. On the other hand, the Questions Controller is responsible for creating, modifying, and deleting individual questions within a questionnaire. Questions can come in various types, such as checkboxes, multiple choice, text boxes, and more. However, each question object will always belong to a particular questionnaire. However, the current implementation suffers from several issues, such as mixing the responsibilities of the two controllers, using methods with identical names for different functionalities, and unclear or unused functionalities. Therefore, to improve the code quality and functionality, the two controllers should be implemented separately and adhere to the CRUD operations as much as possible. Additionally, the code needs to be refactored and optimized for better performance, and unused or unclear methods should be discarded. Finally, comprehensive tests should be written to ensure that the code is functioning correctly and free of code smells.&lt;br /&gt;
&lt;br /&gt;
==Goals of this Project==&lt;br /&gt;
The goals of this Project are:&lt;br /&gt;
&lt;br /&gt;
#Separating the responsibilities of the QuestionnairesController and QuestionsController&lt;br /&gt;
#Fix bugs in the existing functionality&lt;br /&gt;
#Implementing CRUD operations for each controller&lt;br /&gt;
#Discarding unused or unclear functionality&lt;br /&gt;
#Writing tests for the two controllers&lt;br /&gt;
&lt;br /&gt;
By achieving these goals, both the controllers can have their basic CRUD functionalities as well as it will also ensure that the code readability and functionality of the code for the two controllers is increased. It will also help in resolving the existing bugs which will increase correctness of the code.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
&lt;br /&gt;
A considerable amount of time and effort was necessary to review, understand, and re-implement the previous implementation of QuestionsController and QuestionnairesController. The team started with understanding how the Questionnaires and Questions module work by playing around with the Expertiza website. Once we had understanding of the flow, we started understanding the existing code written in the controllers. At first glance, it was visible that the QuestionnairesController was handling all the CRUD operations of Questions as well. We identified what functionalities did not belong in the QuestionnairesController and which redundant code had to be removed. The issues that we have addressed in our reimplementation project are listed as follows.&lt;br /&gt;
&lt;br /&gt;
*'''Separating the responsibilities of the QuestionnairesController and QuestionsController:''' The code snippets below are part of the original implementation of the QuestionnairesController. However, according to design principles, the QuestionsController should be responsible to handle the CRUD operations for questions. We reimplemented the CRUD operations and separated the responsibilities of each controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def add_new_questions&lt;br /&gt;
    questionnaire_id = params[:id] unless params[:id].nil?&lt;br /&gt;
    # If the questionnaire is being used in the active period of an assignment, delete existing responses before adding new questions&lt;br /&gt;
    if AnswerHelper.check_and_delete_responses(questionnaire_id)&lt;br /&gt;
      flash[:success] = 'You have successfully added a new question. Any existing reviews for the questionnaire have been deleted!'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:success] = 'You have successfully added a new question.'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
    ((num_of_existed_questions + 1)..(num_of_existed_questions + params[:question][:total_num].to_i)).each do |i|&lt;br /&gt;
      question = Object.const_get(params[:question][:type]).create(txt: '', questionnaire_id: questionnaire_id, seq: i, type: params[:question][:type], break_before: true)&lt;br /&gt;
      if question.is_a? ScoredQuestion&lt;br /&gt;
        question.weight = params[:question][:weight]&lt;br /&gt;
        question.max_label = 'Strongly agree'&lt;br /&gt;
        question.min_label = 'Strongly disagree'&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      question.size = '50, 3' if question.is_a? Criterion&lt;br /&gt;
      question.size = '50, 3' if question.is_a? Cake&lt;br /&gt;
      question.alternatives = '0|1|2|3|4|5' if question.is_a? Dropdown&lt;br /&gt;
      question.size = '60, 5' if question.is_a? TextArea&lt;br /&gt;
      question.size = '30' if question.is_a? TextField&lt;br /&gt;
&lt;br /&gt;
      begin&lt;br /&gt;
        question.save&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = $ERROR_INFO&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to edit_questionnaire_path(questionnaire_id.to_sym)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; add_new_questions method in the questionnaire controller was responsible for creating questionnaire however it is a basic functionality of questions controller, hence was remove from the questionnaire's controller.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def update&lt;br /&gt;
    # If 'Add' or 'Edit/View advice' is clicked, redirect appropriately&lt;br /&gt;
    if params[:add_new_questions]&lt;br /&gt;
      # redirect_to action: 'add_new_questions', id: params.permit(:id)[:id], question: params.permit(:new_question)[:new_question]&lt;br /&gt;
      nested_keys = params[:new_question].keys&lt;br /&gt;
      permitted_params = params.permit(:id, :new_question =&amp;gt; nested_keys)&lt;br /&gt;
      redirect_to action: 'add_new_questions', id: permitted_params[:id], question: permitted_params[:new_question]&lt;br /&gt;
    elsif params[:view_advice]&lt;br /&gt;
      redirect_to controller: 'advice', action: 'edit_advice', id: params[:id]&lt;br /&gt;
    else&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      begin&lt;br /&gt;
        # Save questionnaire information&lt;br /&gt;
        @questionnaire.update_attributes(questionnaire_params)&lt;br /&gt;
&lt;br /&gt;
        # Save all questions&lt;br /&gt;
        unless params[:question].nil?&lt;br /&gt;
          params[:question].each_pair do |k, v|&lt;br /&gt;
            @question = Question.find(k)&lt;br /&gt;
            # example of 'v' value&lt;br /&gt;
            # {&amp;quot;seq&amp;quot;=&amp;gt;&amp;quot;1.0&amp;quot;, &amp;quot;txt&amp;quot;=&amp;gt;&amp;quot;WOW&amp;quot;, &amp;quot;weight&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;, &amp;quot;size&amp;quot;=&amp;gt;&amp;quot;50,3&amp;quot;, &amp;quot;max_label&amp;quot;=&amp;gt;&amp;quot;Strong agree&amp;quot;, &amp;quot;min_label&amp;quot;=&amp;gt;&amp;quot;Not agree&amp;quot;}&lt;br /&gt;
            v.each_pair do |key, value|&lt;br /&gt;
              @question.send(key + '=', value) unless @question.send(key) == value&lt;br /&gt;
            end&lt;br /&gt;
            @question.save&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
        flash[:success] = 'The questionnaire has been successfully updated!'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = $ERROR_INFO&lt;br /&gt;
      end&lt;br /&gt;
      redirect_to action: 'edit', id: @questionnaire.id.to_s.to_sym&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; update method in the questionnaire controller was updating both questionnaire and questions controller. As we want to separate the responsibility of both the controllers, there are two separate method in each controller updating the respective controllers.&lt;br /&gt;
*'''Discard unused functionality and redundant code:''' The following code snippets were unused in the original implementation so we discarded them.&lt;br /&gt;
'''QUESTIONNAIRES CONTROLLER'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&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;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; Questionnaire is being created with the help of create method, create_questionnaire is a redundant method.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def save_all_questions&lt;br /&gt;
    questionnaire_id = params[:id]&lt;br /&gt;
    begin&lt;br /&gt;
      if params[:save]&lt;br /&gt;
        params[:question].each_pair do |k, v|&lt;br /&gt;
          @question = Question.find(k)&lt;br /&gt;
          # example of 'v' value&lt;br /&gt;
          # {&amp;quot;seq&amp;quot;=&amp;gt;&amp;quot;1.0&amp;quot;, &amp;quot;txt&amp;quot;=&amp;gt;&amp;quot;WOW&amp;quot;, &amp;quot;weight&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;, &amp;quot;size&amp;quot;=&amp;gt;&amp;quot;50,3&amp;quot;, &amp;quot;max_label&amp;quot;=&amp;gt;&amp;quot;Strong agree&amp;quot;, &amp;quot;min_label&amp;quot;=&amp;gt;&amp;quot;Not agree&amp;quot;}&lt;br /&gt;
          v.each_pair do |key, value|&lt;br /&gt;
            @question.send(key + '=', value) unless @question.send(key) == value&lt;br /&gt;
          end&lt;br /&gt;
&lt;br /&gt;
          @question.save&lt;br /&gt;
          flash[:success] = 'All questions have been successfully saved!'&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = $ERROR_INFO&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if params[:view_advice]&lt;br /&gt;
      redirect_to controller: 'advice', action: 'edit_advice', id: params[:id]&lt;br /&gt;
    elsif questionnaire_id&lt;br /&gt;
      redirect_to edit_questionnaire_path(questionnaire_id.to_sym)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; save_all_questions method was used in place of update method in questionnaire controller, that is update in questionnaire was being performed with the help of this method. While implementing basic CRUD, it is no longer needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
    case params[:action]&lt;br /&gt;
    when 'edit'&lt;br /&gt;
      @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
      current_user_has_admin_privileges? ||&lt;br /&gt;
        (current_user_is_a?('Instructor') &amp;amp;&amp;amp; current_user_id?(@questionnaire.try(:instructor_id))) ||&lt;br /&gt;
        (current_user_is_a?('Teaching Assistant') &amp;amp;&amp;amp; session[:user].instructor_id == @questionnaire.try(:instructor_id))&lt;br /&gt;
    else&lt;br /&gt;
      current_user_has_student_privileges?&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; Authorisation has been removed in the new implementation, so it is no longer needed. action_allowed method used to allow certain actions based on the session created by the login credentials.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def new&lt;br /&gt;
    @questionnaire = Object.const_get(params[:model].split.join).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:model].split.join&lt;br /&gt;
  rescue StandardError&lt;br /&gt;
    flash[:error] = $ERROR_INFO&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def edit&lt;br /&gt;
    @questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
    redirect_to Questionnaire if @questionnaire.nil?&lt;br /&gt;
    session[:return_to] = request.original_url&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def add_new_questions&lt;br /&gt;
    questionnaire_id = params[:id] unless params[:id].nil?&lt;br /&gt;
    # If the questionnaire is being used in the active period of an assignment, delete existing responses before adding new questions&lt;br /&gt;
    if AnswerHelper.check_and_delete_responses(questionnaire_id)&lt;br /&gt;
      flash[:success] = 'You have successfully added a new question. Any existing reviews for the questionnaire have been deleted!'&lt;br /&gt;
    else&lt;br /&gt;
      flash[:success] = 'You have successfully added a new question.'&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    num_of_existed_questions = Questionnaire.find(questionnaire_id).questions.size&lt;br /&gt;
    ((num_of_existed_questions + 1)..(num_of_existed_questions + params[:question][:total_num].to_i)).each do |i|&lt;br /&gt;
      question = Object.const_get(params[:question][:type]).create(txt: '', questionnaire_id: questionnaire_id, seq: i, type: params[:question][:type], break_before: true)&lt;br /&gt;
      if question.is_a? ScoredQuestion&lt;br /&gt;
        question.weight = params[:question][:weight]&lt;br /&gt;
        question.max_label = 'Strongly agree'&lt;br /&gt;
        question.min_label = 'Strongly disagree'&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      question.size = '50, 3' if question.is_a? Criterion&lt;br /&gt;
      question.size = '50, 3' if question.is_a? Cake&lt;br /&gt;
      question.alternatives = '0|1|2|3|4|5' if question.is_a? Dropdown&lt;br /&gt;
      question.size = '60, 5' if question.is_a? TextArea&lt;br /&gt;
      question.size = '30' if question.is_a? TextField&lt;br /&gt;
&lt;br /&gt;
      begin&lt;br /&gt;
        question.save&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = $ERROR_INFO&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    redirect_to edit_questionnaire_path(questionnaire_id.to_sym)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; add_new_questions method is now part of responsibility of questions controller as create method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def save_all_questions&lt;br /&gt;
    questionnaire_id = params[:id]&lt;br /&gt;
    begin&lt;br /&gt;
      if params[:save]&lt;br /&gt;
        params[:question].each_pair do |k, v|&lt;br /&gt;
          @question = Question.find(k)&lt;br /&gt;
          # example of 'v' value&lt;br /&gt;
          # {&amp;quot;seq&amp;quot;=&amp;gt;&amp;quot;1.0&amp;quot;, &amp;quot;txt&amp;quot;=&amp;gt;&amp;quot;WOW&amp;quot;, &amp;quot;weight&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;, &amp;quot;size&amp;quot;=&amp;gt;&amp;quot;50,3&amp;quot;, &amp;quot;max_label&amp;quot;=&amp;gt;&amp;quot;Strong agree&amp;quot;, &amp;quot;min_label&amp;quot;=&amp;gt;&amp;quot;Not agree&amp;quot;}&lt;br /&gt;
          v.each_pair do |key, value|&lt;br /&gt;
            @question.send(key + '=', value) unless @question.send(key) == value&lt;br /&gt;
          end&lt;br /&gt;
&lt;br /&gt;
          @question.save&lt;br /&gt;
          flash[:success] = 'All questions have been successfully saved!'&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    rescue StandardError&lt;br /&gt;
      flash[:error] = $ERROR_INFO&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if params[:view_advice]&lt;br /&gt;
      redirect_to controller: 'advice', action: 'edit_advice', id: params[:id]&lt;br /&gt;
    elsif questionnaire_id&lt;br /&gt;
      redirect_to edit_questionnaire_path(questionnaire_id.to_sym)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def save&lt;br /&gt;
    @questionnaire.save!&lt;br /&gt;
    save_questions @questionnaire.id unless @questionnaire.id.nil? || @questionnaire.id &amp;lt;= 0&lt;br /&gt;
    undo_link(&amp;quot;Questionnaire \&amp;quot;#{@questionnaire.name}\&amp;quot; has been updated successfully. &amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # save questions that have been added to a questionnaire&lt;br /&gt;
  def save_new_questions(questionnaire_id)&lt;br /&gt;
    if params[:new_question]&lt;br /&gt;
      # The new_question array contains all the new questions&lt;br /&gt;
      # that should be saved to the database&lt;br /&gt;
      params[:new_question].keys.each_with_index do |question_key, index|&lt;br /&gt;
        q = Question.new&lt;br /&gt;
        q.txt = params[:new_question][question_key]&lt;br /&gt;
        q.questionnaire_id = questionnaire_id&lt;br /&gt;
        q.type = params[:question_type][question_key][:type]&lt;br /&gt;
        q.seq = question_key.to_i&lt;br /&gt;
        if @questionnaire.type == 'QuizQuestionnaire'&lt;br /&gt;
          # using the weight user enters when creating quiz&lt;br /&gt;
          weight_key = &amp;quot;question_#{index + 1}&amp;quot;&lt;br /&gt;
          q.weight = params[:question_weights][weight_key.to_sym]&lt;br /&gt;
        end&lt;br /&gt;
        q.save unless q.txt.strip.empty?&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def delete_questions(questionnaire_id)&lt;br /&gt;
    # Deletes any questions that, as a result of the edit, are no longer in the questionnaire&lt;br /&gt;
    questions = Question.where('questionnaire_id = ?', questionnaire_id)&lt;br /&gt;
    @deleted_questions = []&lt;br /&gt;
    questions.each do |question|&lt;br /&gt;
      should_delete = true&lt;br /&gt;
      unless question_params.nil?&lt;br /&gt;
        params[:question].each_key do |question_key|&lt;br /&gt;
          should_delete = false if question_key.to_s == question.id.to_s&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      next unless should_delete&lt;br /&gt;
&lt;br /&gt;
      question.question_advices.each(&amp;amp;:destroy)&lt;br /&gt;
      # keep track of the deleted questions&lt;br /&gt;
      @deleted_questions.push(question)&lt;br /&gt;
      question.destroy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; destroy method in the questions controller was responsible for deleting the questions, so it was unused method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def save_questions(questionnaire_id)&lt;br /&gt;
    delete_questions questionnaire_id&lt;br /&gt;
    save_new_questions questionnaire_id&lt;br /&gt;
&lt;br /&gt;
    if params[:question]&lt;br /&gt;
      params[:question].keys.each do |question_key|&lt;br /&gt;
        if params[:question][question_key][:txt].strip.empty?&lt;br /&gt;
          # question text is empty, delete the question&lt;br /&gt;
          Question.delete(question_key)&lt;br /&gt;
        else&lt;br /&gt;
          # Update existing question.&lt;br /&gt;
          question = Question.find(question_key)&lt;br /&gt;
          Rails.logger.info(question.errors.messages.inspect) unless question.update_attributes(params[:question][question_key])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''QUESTIONS CONTROLLER'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 def action_allowed?&lt;br /&gt;
    current_user_has_ta_privileges?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
-&amp;gt; Authorisation is not required while creating CRUD end points.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def new&lt;br /&gt;
    @question = Question.new&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def edit&lt;br /&gt;
    @question = Question.find(params[:id])&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Minor Bug fixes in the existing code:''' The following bugs in the existing code needed to be fixed.&lt;br /&gt;
#User was not able to delete Questionnaire: After careful debugging, we found that a path for delete questionnaire was not defined in the routes.rb file.&lt;br /&gt;
[[File:delete-1.png|center|border|800px|]]&lt;br /&gt;
[[File:delete-2.png|center|border|800px|]]&lt;br /&gt;
#Nil Class Error while saving empty questionnaire: We kept a check in the save_all_questions method to handle the error and allow the questionnaire to be saved empty.&lt;br /&gt;
[[File:Nilerror.png|center|border|800px|]]&lt;br /&gt;
*'''Fix the update method in QuestionnairesController:''' The original implementation of the method could not update the attributes of the questionnaire and it was used only to update the questions of that questionnaire. We reimplemented the method to update both the questionnaire attributes and each question if a change was made to them.&lt;br /&gt;
&lt;br /&gt;
Initial code for the Questions and Questionnaires controller can be referred here - &lt;br /&gt;
*Questionnaries Controller - https://github.com/mundra-ankur/expertiza/blob/main/app/controllers/questionnaires_controller.rb&lt;br /&gt;
*Questions Controller - https://github.com/mundra-ankur/expertiza/blob/main/app/controllers/questions_controller.rb&lt;br /&gt;
&lt;br /&gt;
Code was reimplemented to create basic CRUD operations after the methods of the controllers were fixed for the bugs. Then the methods were converted to basic CRUD operations which are described below.&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionsController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questions_controller.rb questions_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questions with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the question parameters and creates a new question.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.&lt;br /&gt;
#types: This is a GET endpoint that responds with the list of question types.&lt;br /&gt;
&lt;br /&gt;
[[File:Q1.png|center|border|800px|]]&lt;br /&gt;
[[File:Q2.png|center|border|800px|]]&lt;br /&gt;
[[File:Q30.png|center|border|800px|]]&lt;br /&gt;
[[File:Q4.png|center|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
*'''Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController:''' We reimplemented the following methods to create the required endpoints in [https://github.com/expertiza/reimplementation-back-end/blob/0b09c15466e5d9865663ed2253d9f37a2e1ca1d9/app/controllers/api/v1/questionnaires_controller.rb questionnaires_controller.rb].&lt;br /&gt;
#index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.&lt;br /&gt;
#show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.&lt;br /&gt;
#create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.&lt;br /&gt;
#destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.&lt;br /&gt;
#update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.&lt;br /&gt;
#copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.&lt;br /&gt;
#toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.&lt;br /&gt;
&lt;br /&gt;
[[File:Q50.png|center|border|800px|]]&lt;br /&gt;
[[File:Q6.png|center|border|800px|]]&lt;br /&gt;
[[File:Q7.png|center|border|800px|]]&lt;br /&gt;
&lt;br /&gt;
==Testing Methodology==&lt;br /&gt;
Our work was to reimplement the QuestionsController.rb and QuestionnairesController.rb and create JSON endpoints for each CRUD operation. Since all the operations had dependencies on other Models and Helper functions which are not included in the reimplementation-back-end, it is not possible for us to use RSpec as the testing tool. To test each endpoint, we have used Postman to send a request to each endpoint. '''The video with the testing plan is available at''' https://bit.ly/E2321&lt;br /&gt;
&lt;br /&gt;
'''Using Postman to test endpoints:'''&amp;lt;br&amp;gt;&lt;br /&gt;
We tested each route of the QuestionsController and QuestionnairesController to test whether the expected response is obtained. We made valid requests by passing the right parameters to each endpoint to check whether each method behaves as expected. We then made requests with incorrect number of parameters, invalid parameter types and values to check whether the endpoint throws a status 422 Invalid Request as the response. This method of testing via postman helped us ensure that each API endpoint handles the valid and invalid requests and behaves as intended.&lt;br /&gt;
&lt;br /&gt;
For automated testing, these Rspec files https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questionnaires_spec.rb and https://github.com/Vineet2311/reimplementation-back-end/blob/main/spec/requests/api/v1/questions_spec.rb can be used in the future implementations when all the models and helper classes needed have been added to the repository. These test cases ensures that the API returns the expected responses for valid and invalid requests.&lt;br /&gt;
&lt;br /&gt;
== Relevant Links ==&lt;br /&gt;
* '''Github Repository:''' https://github.com/Vineet2311/reimplementation-back-end&lt;br /&gt;
* '''Pull Request:''' https://github.com/expertiza/reimplementation-back-end/pull/20&lt;br /&gt;
* '''VCL Server:''' http://152.7.177.38:8080&lt;br /&gt;
* '''Test Video Link:''' https://bit.ly/E2321&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
This feature was created as part of Dr. Edward Gehringer's &amp;quot;CSC/ECE 517: Object-Oriented Design and Development&amp;quot; class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Q50.png&amp;diff=148718</id>
		<title>File:Q50.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Q50.png&amp;diff=148718"/>
		<updated>2023-03-30T00:12:56Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Q30.png&amp;diff=148717</id>
		<title>File:Q30.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Q30.png&amp;diff=148717"/>
		<updated>2023-03-30T00:12:10Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Q7.png&amp;diff=148716</id>
		<title>File:Q7.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Q7.png&amp;diff=148716"/>
		<updated>2023-03-30T00:10:57Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Q6.png&amp;diff=148715</id>
		<title>File:Q6.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Q6.png&amp;diff=148715"/>
		<updated>2023-03-30T00:10:37Z</updated>

		<summary type="html">&lt;p&gt;Vchheda: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vchheda</name></author>
	</entry>
</feed>