CSC/ECE 517 Fall 2024 - E2474. Reimplement student quizzes controller.rb
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
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
- Akhilesh Neeruganti (asneerug@ncsu.edu)
- Krishna Pallavalli (kpallav@ncsu.edu)
- Aarya Rajoju (arajoju@ncsu.edu)
Mentor: Richard Li (rli14@ncsu.edu)
Relevant Links
- This wiki page contains detailed information on the previous team's work on this feature.
- Github Repository: https://github.com/neerua08/reimplementation-back-end
- Pull Request: https://github.com/expertiza/reimplementation-back-end/pull/141
- Demo Video Link: https://youtu.be/hi_4GVLCpdY