CSC/ECE 517 Fall 2024 - E2474. Reimplement student quizzes controller.rb

From Expertiza_Wiki
Jump to navigation Jump to search

This wiki page is about E2474 Phase 2 for Expertiza.

Background

Expertiza is a Ruby on Rails based open source project. The Expertiza project is software for creating reusable learning objects through peer review. It also supports team projects and the submission of almost any document type, including URLs and wiki pages. The goal is to foster team collaboration through projects and provide a robust way to give feedback for these projects.

Problem Statement

For this project, we are expected to reimplement the student_quizzes_controller.rb file in the reimplementation-backend repository of Expertiza. This controller handles scoring, creating, and recording responses for quizzes that are done by students or reviewers for an assignment. The main issue with the previous implementation is that it violates several Rails design principles such as DRY violations. Along with this, various other issues that need to be addressed include code repetition, unclear method comments, and ambiguous variable names. The overall idea of this project is to ensure that we maintain the previous functionality while adhering to the best design practices.

Specific Issues

  • Single-Responsibility Principle - Various functionalities are done in the student_quizzes_controller.rb that should be deferred to other models or controllers.
  • DRY Violations - There is a good amount of code repetition in the code that could be consolidated to a method.
  • Unclear Method and Variable Names - There are ambiguous methods names and variable names that should be changed. We can also add method comments to help explain functionality.

Design Plan

Single-Responsibility Principle

calculate_score

This method gets a response map and then gets the score from that response map. We can instead ask the ResponseMap model to get this information.

Solution: Instead of response_map.score, we create a get_score method in ResponseMap model.

process_answers

This method attempts to edit the submitted_answer field in ResponseMap. This should be done by ResponseMap model instead of our controller.

Solution: We will fully move the process_answers method into the ResponseMap model.

check_instructor_role

The goal of this method is to get the role ID of the user to make sure they are an instructor. We want to let the Role model check this instead of checking it in the controller.

Solution: Instead of "current_user.role_id == 2", we will make use of the instructor? method in Role to check if the current user is an instructor.

Other methods

  • Several methods could be moved into the model classes in adherence to MVC architecture. This includes build_response_map, etc.

DRY Violations

find_resource_by_id

This is a method that is frequently called in this controller. We plan to separate this functionality into a concern or a shared utility function.

Solution: We will move this method into a separate concern that is included in this controller. This can be used in other controllers as well.

New Skippable Feature

We plan to add a new field for questions that allows the instructor to decide whether a question is required or skippable. This can be extended outside of quizzes.

Renaming Method and Variable Names

  • Rename the methods for assign_quiz_to_student and submit_answer to clarify their purpose. We can also add method comments to help with this.
  • Refactor variable names to better reflect their purpose. The image below shows that model is not the best name along with find_resource_by_id

Main Methods to Create or Enhance

 #  Method Purpose Description Commit
1 calculate_score , process_answers Ensure MVC compliance and adherence to the Single-Responsibility Principle Move both calculate_score and process_answers to the ResponseMap model, allowing the controller to focus only on handling requests and delegating logic to models. calculate_score Commit: Link

process_answers Commit: Link

2 find_resource_by_id Reduce DRY violations Implement this as a shared utility function to eliminate duplicate code and streamline resource retrieval in the controller. Commit: Link
3 check_instructor_role Improve code readability Move the check_instructor_role method to the Role model, ensuring that role-related logic resides within the model rather than the controller. Commit: Link
4 build_response_map Improve modularity Transfer these methods from the controller to appropriate model classes, which aligns with the MVC pattern and keeps controller methods concise. Commit: Link
5 assign_quiz_to_student Improve code readability Rename these methods to more descriptive names and add comments to explain functionality, making the codebase easier to understand and maintain. Commit: Link

Implementation

Files Added or Changed

  • Added student_quizzes_controller.rb
  • Changed ResponseMap.rb
  • Added resource_finder.rb
  • Changed question.rb and questionnaire.rb

Changes Made

 #  Change Description Old New
1 Initially, we calculate_score directly called the score variable in the controller. We decided to implement a get score to adhere to SRP. We also implemented a new calculate_score as the old version did not implement a method that calculates anything.
2 We moved all of process_answer into ResponseMap to adhere with SRP.
3 find_resource_by_id was called frequently in this controller, so we moved this into a separate concern which is called in this controller. The file for this is resource_finder.rb.
4 check_instructor_role used to check the role ID number, which violates SRP. We decided to use the instructor? method for role to determine if the current user is an instructor.
5 Added some new functionality to make questions skippable or not skippable in questionnaires. This includes changes in the database schema to add this new field. No old code.
6 Clearer method names and method comments were added in this controller. One example is assign_quiz_to_student, which is shown in the images.

Test Plan

As we are reimplementing this file from scratch, we plan to do some manual testing to verify our code. If time permits, we can add some automated tests. Currently, we plan to use a variety of tools to test our code including:

  • Postman - Test our API calls for the controller to ensure their functionality. The main purpose is to validate the behavior of the controller. This can be done by testing all relevant CRUD operations for quiz creation, submission, and scoring, verifying that the controller responds with appropriate status codes, ensure that all input validations are working as expected including edge cases, and validate that the controller adheres to any role-based access restrictions. Examples of what we have done are shown below.
  • Automated RSpec Tests - Test the various methods in our controller to determine if they are functioning as expected. The main purpose is to verify the internal logic of the controller and related methods ensuring they are functioning as expected. This can be done by creating unit tests for methods within the controller especially methods that will be refactored or moved to the model, creating model tests for if any logic is moved to the models to verify that the new functionality works correctly, and create controller tests to ensure that the controller actions work as expected like assigning quizzes to students, submitting answers and recording results, and calculating scores correctly.
  • Test Coverage - Using SimpleCov to ensure sufficient test coverage of all key methods and code paths, preventing any untested code from being deployed. We can do this by integrating SimpleCov to measure code coverage across the entire application, create coverage goals and aim for like a high code coverage (e.g., 90% or higher) to ensure all key methods in the controller and related models are thoroughly tested, monitor coverage reports to identify any untested methods or areas of the codebase and add tests for those areas as needed, and refactor based on coverage so if we see significant gaps in test coverage, we can refactor the tests or implementation to ensure better coverage.

We don't plan on adding new scenarios but instead we plan on retesting scenarios: creating a new student quiz, handling invalid student quiz creation, calculating quiz score, assigning quiz to student, submitting quiz answers, and updating a student quiz to see if those scenarios still work when we reimplement student_quizzes_controller.rb as a whole. We might add multiple scenarios as we go.

Postman API Tests

  • POST /api/v1/students_quizzes: Endpoint to login as the instructor

  • POST /api/v1/students_quizzes: Endpoint to create a quiz

  • POST /api/v1/students_quizzes/assign: Endpoint to assign quiz to participant

  • POST /api/v1/students_quizzes/submit_quiz: Endpoint to submit answers

  • GET /api/v1/students_quizzes/7/get_score: Endpoint to get score and for this test use 7 as our response id

  • PUT /api/v1/students_quizzes/9: Endpoint to update quiz

  • DELETE /api/v1/students_quizzes/3: Endpoint to delete a quiz

Future Work

  • More methods can be moved into other models to respect MVC including quiz_already_assigned?, find_response_map_for_current_user, etc.
  • Some method names can be further improved.
  • Some frontend changes may need to be added to include the new skippable feature added.
  • More testing can be added to test new features that have been added thoroughly.

Team Members

  1. Akhilesh Neeruganti (asneerug@ncsu.edu)
  2. Krishna Pallavalli (kpallav@ncsu.edu)
  3. Aarya Rajoju (arajoju@ncsu.edu)

Mentor: Richard Li (rli14@ncsu.edu)

Relevant Links