CSC/ECE 517 Spring 2023 - E2345. Reimplement QuestionnairesController and QuestionsController

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

This page gives a description of the changes made for the questions_controller.rb, questionnaire_controller.rb, question.rb & questionnaire.rb of Expertiza based OSS project.

Problem Statement

What is needed: 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:

  1. Improving the clarity and conciseness of code: 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.
  2. Discarding unused functionality: Any unused functionality should be removed from the controllers. This will help to reduce complexity and make the code easier to maintain.
  3. Writing tests for the two controllers: 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.
  4. Reimplement Questions and Questionnaires models: Reimplement the two models to facilitate the endpoints of the respective controllers.
  5. Writing tests for the two models: 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.

General Design Goals

  • Ensure all prior/expected functionality is working correctly, and if not, make any repairs or changes necessary.
  • Ensure that the each of the models and controllers have loose coupling and tight cohesion.
  • DRY out prior implementation's controller and model methods which have functionality that already exists within the expertiza system.
  • Ensure all present test cases still work properly after making the above changes and create additional test cases.

Current Implementation

Plan for current implementation for the code can be found here E2321. We completed these responsibilities in the previous project:

  1. Separating the responsibilities of the QuestionnairesController and QuestionsController
  2. Fix bugs in the existing functionality
  3. Implementing CRUD operations for each controller
  4. Discarding unused or unclear functionality
  5. Writing tests for the two controllers

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.)

  • Reimplement CRUD functionality and create JSON endpoints in QuestionsController: We reimplemented the following methods to create the required endpoints in questions_controller.rb.
  1. index: This is a GET endpoint that responds with a list of all questions with their attributes.
  2. show: This is a GET endpoint that accepts a question id and responds with the attributes of that question if it exists.
  3. create: This is a POST endpoint that accepts the question parameters and creates a new question.
  4. destroy: This is a DELETE endpoint that accepts a question ID and deletes that question.
  5. update: This is a PUT endpoint that accepts a question ID and parameters, and, updates that question with the given parameters.
  6. types: This is a GET endpoint that responds with the list of question types.
  • Reimplement CRUD functionality and create JSON endpoints in QuestionnairesController: We reimplemented the following methods to create the required endpoints in questionnaires_controller.rb.
  1. index: This is a GET endpoint that responds with a list of all questionnaires with their attributes.
  2. show: This is a GET endpoint that accepts a questionnaire id and responds with the attributes of that questionnaire if it exists.
  3. create: This is a POST endpoint that accepts the questionnaire parameters and creates a new questionnaire.
  4. destroy: This is a DELETE endpoint that accepts a questionnaire ID and deletes that questionnaire.
  5. update: This is a PUT endpoint that accepts a questionnaire ID and parameters, and, updates that questionnaire with the given parameters.
  6. copy: This is a POST endpoint that accepts a questionnaire ID and creates a new questionnaire (copy) with the same attributes of that questionnaire.
  7. toggle_access: This is a GET endpoint that changes the access from public to private and vice versa.

Implementation Plan

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:
1. Reimplement basic version of question.rb and questionnaire.rb such that it facilitates the controllers' CRUD operations.

  • Add associations to user.rb, role.rb, assignment.rb only.
  • Implement only the functions that depend on the above classes.

2. Write comprehensive test cases for both models using RSpec.
3. Reimplement questions_controller.rb and questionnaires_controller.rb to incorporate the feedback received in E2321. The feedback is as follows:

  • Optimize the Create method in questionnaires_controller.rb such that individual fields does not need to be set and validated.
 # POST on /questionnaires
 def create
   if params[:questionnaire][:name].blank?
     render json: "Questionnaire name cannot be blank.", status: :unprocessable_entity
   end
   begin
     display_type = params[:questionnaire][:type].split('Questionnaire')[0]
     @questionnaire = Object.const_get(params[:questionnaire][:type]).new if Questionnaire::QUESTIONNAIRE_TYPES.include? params[:questionnaire][:type]
     @questionnaire.private = params[:questionnaire][:private] == 'true'
     @questionnaire.name = params[:questionnaire][:name]
     @questionnaire.instructor_id = 6 # session[:user].id
     @questionnaire.min_question_score = params[:questionnaire][:min_question_score]
     @questionnaire.max_question_score = params[:questionnaire][:max_question_score]
     @questionnaire.type = params[:questionnaire][:type]
     if %w[AuthorFeedback CourseSurvey TeammateReview GlobalSurvey AssignmentSurvey BookmarkRating].include?(display_type)
       display_type = (display_type.split(/(?=[A-Z])/)).join('%')
     end
     @questionnaire.display_type = display_type
     @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL
     @questionnaire.save
     render json: @questionnaire, status: :created
   rescue StandardError
     msg = $ERROR_INFO
     render json: msg, status: :unprocessable_entity
   end
 end
  • Implement an endpoint to delete all questions associated with a questionnaire.
 # DELETE on /questions/delete_all/<questionnaire_id>
 # Endpoint to delete all questions associated to a particular questionnaire.
 def delete_all
   begin
     @questionnaire = Questionnaire.find(params[:id])
     @questionnaire.questions.destroy_all
     msg = "All questions for Questionnaire ID:" + params[:id].to_s + " has been successfully deleted!"
     render json: msg, status: :ok
   rescue
     render json: $ERROR_INFO, status: :unprocessable_entity
   end
 end
  • Add a validation to allow deletion of questionnaire only if all questions that belongs to it are deleted first.
 # DELETE on /questionnaires/:id
 def destroy
   begin
     @questionnaire = Questionnaire.find(params[:id])
   rescue
     render json: $ERROR_INFO, status: :not_found and return
   end
   begin
     name = @questionnaire.name
     questions = @questionnaire.questions
     # questions.each do |question|
     #   question.delete
     # end
     unless questions.nil?
       msg = "This questionnaire has questions associated with it. Use this endpoint to delete all questions for the questionnaire: "
       link = "/questions/delete_all/" + @questionnaire.id.to_s
       msg += link
       render json: msg and return
     else
       @questionnaire.delete
       render json: "The questionnaire \"#{name}\" has been successfully deleted.", status: :ok and return
     end
   rescue StandardError => e
     render json: e.message, status: :unprocessable_entity and return
   end
 end

4. Write comprehensive test cases for both controllers using RSpec.

Testing Methodology

  • Rspec tests for QuestionnairesController and QuestionsController had been added in the previous project E2321 but had not been executed due to missing dependencies. This project focuses on implementing them and getting automated test cases running as expected.

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.

  • 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.)
  • Demonstrating working of API endpoints on Postman.

Relevant Links

Contributors

This feature was created as part of Dr. Edward Gehringer's "CSC/ECE 517: Object-Oriented Design and Development" class, Spring 2023. The contributors were: Vineet Vimal Chheda, Rohan Jigarbhai Shah, and Aditya Srivastava. Our project mentor was Ankur Mundra (amundra@ncsu.edu)