CSC/ECE 517 Fall 2024 - E2452. Refactor review mapping controller.rb
Expertiza Background
The open-source project Expertiza is built using Ruby on Rails, maintained by both the staff and students at NC State. This platform grants instructors complete authority over managing class assignments. Expertiza is packed with versatile tools to support various types of assignments, including options for peer evaluations, forming groups, and adding topics. For a comprehensive overview of all that Expertiza provides, visit the Expertiza wiki.
About Controller
The `review_mapping_controller` function is responsible for assigning reviewers to specific assignments. This controller plays a key role in allocating reviews across different student groups or individuals, handling both peer and self-assessment scenarios. Additionally, it manages student requests for reviews and facilitates extra bonus reviews that align with the assignment's requirements.
Functionality of review_mapping_controller
The `review_mapping_controller` is a vital part of a system dedicated to managing the assignment and allocation of reviewers for different types of evaluations, such as peer reviews and self-assessments. Its main role is to coordinate the assignment of these reviews across individual students or various groups, using an intricate process that factors in elements like fairness, diverse perspectives, and alignment with assignment criteria. Through this coordination, the controller ensures that every participant receives a thorough and balanced assessment, supporting the overall quality and reliability of the evaluation process.
In addition, the `review_mapping_controller` is essential for handling student requests for additional assessments, often driven by needs for extra feedback, additional credit opportunities, or reevaluation. When processing these requests, the controller must adhere to assignment guidelines and carefully evaluate the feasibility of granting extra assessments without affecting the integrity or fairness of the review process. This may involve accounting for practical constraints, such as reviewer availability and workload distribution, to ensure an equitable experience for all participants.
Problem Statement
The `review_mapping_controller` poses challenges due to its extensive size, complexity, and lack of comments, which make it hard for developers to fully understand its functions. To improve this, a thorough refactoring is recommended to divide lengthy methods into smaller, more understandable sections. This approach would break down complex logic into modular parts, each handling a particular task within the controller’s scope. Additionally, refactoring should focus on eliminating redundant code, consolidating repeated segments into reusable functions or utilities to improve code quality and minimize errors. By reorganizing the controller code and enhancing its documentation, developers can gain a clearer insight into its functionality, simplifying maintenance, troubleshooting, and potential updates.
Tasks
1. Refine Extensive Methods: Methods like `assign_reviewer_dynamically`, `add_reviewer`, `automatic_review_mapping`, and `peer_review_strategy` will be further broken down for greater clarity and efficiency.
2. Clarify Variable Names: Variables will be renamed to make their roles more transparent, enhancing readability and comprehension.
3. Use Subclass Methods Instead of Switch Statements: Existing switch statements will be replaced with subclass methods, contributing to a more modular and scalable code structure.
4. Introduce Subclass Models: New models for subclasses will be implemented to streamline organization and simplify management.
5. Eliminate Hardcoded Parameters: Any hardcoded parameters will be removed to increase adaptability across different use cases.
6. Enhance Comments: Additional comments will be included where helpful, and any vague or redundant comments will be clarified or removed.
7. Expand Test Coverage: The test suite will be extended to ensure thorough testing, particularly following the refactoring process.
Phase 1
- Restructure the `assign_reviewer_dynamically` function to enhance its clarity and modular design.
- Revise and improve the tests related to the `assign_reviewer_dynamically` function.
- Simplify the `add_reviewer` function by breaking down its complex logic into smaller, more manageable components.
- Update and broaden the tests associated with the `add_reviewer` function to ensure proper functionality.
- Refine existing comments and introduce new ones to clarify intricate parts of the code.
- Change variable names to make their purposes clear, allowing for immediate understanding.
- Tackle and fix Code Climate issues to produce cleaner and more efficient code.
- Obtained assignment details using the assignment ID, ensuring that an error message is displayed if a user is invalid (not found in the database), and that reviewer assignments are only made if the reviewer is confirmed as part of the assignment.
- Collected participant details when a user was added to an assignment.
Test Cases
- Verify that `assign_reviewer_dynamically()` correctly assigns a reviewer based on defined criteria.
- Check that `add_reviewer()` successfully adds a reviewer to the system.
- Ensure `automatic_review_mapping()` maps submissions to reviewers automatically.
- Validate the logic of `peer_review_strategy()` for peer reviewer assignments.
- Ensure all variables have been renamed according to the new naming conventions.
- Confirm that all switch statements have been replaced with subclass methods.
- Verify that hardcoded parameters have been removed and replaced with configurable options.
- Check for meaningful comments and the removal of redundant or unclear comments.
- Assess whether the test suite covers all critical functions and edge cases.
- Test dynamic reviewer assignment for edge cases, such as no available reviewers.
Implementation
Restructuring assign_reviewer_dynamically
Original Code
The assign_reviewer_dynamically function contained multiple responsibilities, making it lengthy and challenging to follow.
Updated Code
The function was refactored to focus on specific tasks, such as:
- Validating user eligibility
- Fetching assignment details
- Assigning a reviewer only if they are confirmed as part of the assignment
Revising Tests for assign_reviewer_dynamically
Original Code
- The tests related to the assign_reviewer_dynamically function were limited and did not cover all scenarios.
Updated Code
- The tests have been improved and broadened to cover:
- Valid user scenarios
- Invalid user scenarios (e.g., user not found in the database)
Simplifying add_reviewer
Original Code
- The add_reviewer function had complex logic that hindered readability and maintainability.
Updated Code
- This function was simplified by breaking it down into smaller, manageable components that handle Parameter Validation, Sending notifications
Updating Tests for add_reviewer
Original Code
- The existing tests for add_reviewer were insufficient to ensure the function worked correctly in all situations.
Updated Code
Tests were expanded to include:
- Successful addition of reviewers
- Handling of invalid inputs
Refining Comments and Documentation
Original Code
- Comments in the original code were sparse and often unclear.
Updated Code
Descriptive comments were added throughout the code to explain:
- The purpose of each method
- The logic behind complex code sections
Changing Variable Names
Original Code
- Variable names were generic and did not convey their purposes.
Updated Code
- Variable names have been updated to be more descriptive, making their purposes immediately clear.
Design Document
Current Status
The project has been refactored to improve code readability, modularity, and maintainability. This refactoring has focused on breaking down complex methods into smaller, single-purpose functions, enhancing error handling, and reducing redundant code through reusable helper methods. These changes align with Ruby best practices and the SOLID principles, making the code easier to understand, extend, and maintain.
Highlights of the Refactored Controller:
- Improved modularity with clearly defined helper methods.
- Consistent error handling and validation checks for invalid user assignments and outstanding reviews.
- Reduction in redundant code by centralizing frequently used logic, enhancing the controller's readability and scalability.
Key Changes
1. Modularization of Functions:
- Decomposition of Methods: Long methods such as add_reviewer, assign_reviewer_dynamically, and automatic_review_mapping were broken down into smaller helper methods, e.g., get_participant_or_reviewer, get_review_response_mapping, assign_reviewer_to_contributor, check_for_self_review, and others.
- Guard Clauses: Used guard clauses in methods like assign_reviewer_dynamically to reduce nesting and exit early when conditions are not met, improving clarity.
2. Extraction of Reusable Components:
- Topic and Team Assignment: The logic for assigning reviewers based on topics and for handling teams with or without topics was extracted into assignment_with_topics and assignment_with_no_topics methods, following SRP.
- Dynamic Review Assignment: Introduced modular helper functions (assign_reviewer_based_on_topics, assign_topics_to_reviewer, and assign_team_to_review) to assign topics and teams dynamically, making the main controller logic clearer and more concise.
3. Error Handling and Validation Improvements:
- Error Feedback and Edge Case Handling: Added validations to handle cases where a user or reviewer does not exist or has outstanding reviews, providing informative error messages to users.
- Refined Reviewer Selection Logic: Prevented users from assigning themselves to review their own work (check_for_self_review) and introduced conditions to verify reviewer assignments before proceeding.
4. Automated Review Mapping:
- Helper Methods: Introduced handle_standard_review_mapping and handle_calibrated_and_uncalibrated_artifacts for handling scenarios with or without calibrated artifacts, streamlining the process for assigning review tasks based on specific review needs.
- Dynamic Strategy Application: Created a strategy-based approach (automatic_review_mapping_strategy) to handle review mapping dynamically based on student and submission count, enhancing the flexibility of review assignment.
Principles Applied
- Single Responsibility Principle (SRP): Each method now has a single responsibility, with helper methods extracted for distinct actions.
- Open/Closed Principle: The refactored code can be extended with additional helper functions or strategies without modifying existing methods.
- DRY (Don't Repeat Yourself): Repeated code segments, especially for participant/reviewer/team assignment, were extracted into reusable methods, reducing redundancy.
- Error Handling: Improved resilience by checking for conditions like invalid users, duplicate reviewer assignments, and outstanding reviews.
Code References
1. Single Responsibility Principle (SRP):
- Decomposition of Long Methods: Large methods were divided to ensure each method has a single responsibility. For example:
assign_reviewer_dynamically was split into assign_reviewer_based_on_topics, assignment_with_topics, and assignment_with_no_topics, isolating the logic for dynamic assignment with or without topics.
- add_reviewer was decomposed to include helper methods like assign_reviewer_to_contributor, get_participant_or_reviewer, and check_for_self_review, separating concerns within the reviewer addition process.
- Error Checks: Methods like check_invalid_topic and check_for_self_review handle specific validation tasks, isolating logic to keep main functions focused on their core
operations.
2. Open/Closed Principle:
- Extensible Review Strategies: The assign_reviewer_based_on_topics method allows for adding new assignment strategies without modifying the core method, promoting extensibility.
Dynamic Review Assignment Strategy: Helper methods like assignment_with_topics and assignment_with_no_topics make it easy to introduce additional criteria or rules for assigning topics or teams to reviewers without altering existing logic.
- Automatic Review Mapping Strategy: The automatic_review_mapping_strategy allows flexibility to handle multiple review scenarios (student reviews, submission reviews) by passing parameters, making it easy to adjust the review strategies as needed without modifying the core controller code.
3. DRY (Don't Repeat Yourself):
- Extraction of Common Code: Common logic for fetching assignment, participant, and review mappings was consolidated:
- Methods like get_participant_or_reviewer, get_assignment, and get_review_response_mapping centralize database queries, reducing redundancy in places like add_calibration, assign_reviewer_dynamically, and automatic_review_mapping.
- Review Mapping Logic: Shared review assignment logic across multiple methods, such as assign_topics_to_reviewer and assign_team_to_review, was centralized to avoid repeating topic and team checks for different review paths.
- Error Messages and Flash Notices: Error handling messages, such as those for insufficient or outstanding reviews, were standardized across methods to avoid redundant inline error logic.
4. Enhanced Error Handling:
- Guard Clauses: Guard clauses were added to methods such as assign_reviewer_dynamically and add_reviewer to handle errors early and avoid nested conditional logic. For instance, assign_reviewer_dynamically checks for valid topics and outstanding reviews at the beginning, setting flash messages if conditions are not met.
- Invalid User/Reviewer Checks: In add_reviewer, the method now verifies user existence, preventing invalid users from being assigned. This is handled by checking user_id.nil? and setting flash[:error] if the user is not found.
- Duplicate Assignments: In assign_reviewer_to_contributor, a check for existing reviewer assignments was added to prevent duplicate entries, raising an error if a reviewer is already assigned to the contributor.
Future Scope
A comprehensive testing strategy is being implemented for the `ReviewMappingController` to ensure functionality, reliability, and scalability. This approach includes well-defined test categories and a systematic execution process to rigorously validate both new and existing features. This enhances the controller’s performance, adaptability, and overall quality, providing a solid foundation for current operations and future growth.
General Enhancements and Best Practices
- FactoryBot for Model Setup: Necessary models, including ReviewGrade, Instructor, AssignmentTeam, and others, will be defined in FactoryBot factories. This approach will reduce redundant setup code, improve test readability, and facilitate maintenance and extension.
- Mocking and Spying: RSpec’s allow and expect methods will be utilized to mock dependencies, isolating the logic under test, enhancing reliability, and expediting execution.
- Comprehensive Edge Case Testing: Each method will be tested for edge cases such as empty collections, nil values, and invalid parameters to ensure the controller’s resilience against unexpected inputs.
- Error Handling: Error scenarios will be specifically addressed, particularly cases involving database errors or missing records, to validate the controller’s resilience and stability.
- Flash Message Validation: Tests will be designed to confirm that all flash messages, for both success and failure scenarios, provide accurate and informative feedback to the user.
Test Case Categories and Example Scenarios
Test cases will be organized into the following categories to ensure comprehensive coverage of all functionality in the ReviewMappingController:
1. Validation and Error Handling
- automatic_review_mapping with Invalid Parameters: Test cases will cover scenarios involving missing parameters, negative values (e.g., num_reviews_per_student set to -1), and conflicting options (e.g., both num_reviews_per_student and num_reviews_per_submission provided). Invalid parameters should result in appropriate flash messages, preventing further execution.
- Edge Cases for Flash Messages: Flash messages will be tested to ensure they accurately reflect outcomes, such as when attempting to delete an already-deleted review or submitting an invalid review assignment.
2. State Transitions
- Duplicate Self-Review Prevention in start_self_review: Tests will confirm that the controller prevents duplicate self-review mappings, redirecting the user with a message indicating an existing self-review assignment if applicable.
- New Review Mappings via automatic_review_mapping: Tests will verify that new review mappings are correctly created and that the system state is updated to include these mappings. Expected outcomes include proper redirection and flash messages upon successful execution.
3. Flash Messages & Redirects
- Successful Deletion in delete_metareview: Tests will confirm that the correct success flash message is displayed when a metareview is deleted and that the user is redirected appropriately.
- Forced Deletion After Failure in delete_metareview: Forced deletion cases will be tested to ensure that relevant flash messages are displayed, providing error details and notifying the user of the force option.
4. Boundary and Edge Conditions
- High Volume Handling in automatic_review_mapping: Test cases simulating large numbers of teams and review requests (e.g., hundreds) will validate that the method can handle scalability demands. These cases will focus on performance and stability under load.
- Empty Team List in automatic_review_mapping: Tests will cover scenarios where no teams are available but review parameters are valid. The system should handle these cases gracefully, displaying relevant flash messages regarding the lack of available teams.
Test Execution Process
The following structured process will guide the execution of test cases to ensure comprehensive and consistent coverage:
1. Mock Dependencies: RSpec’s allow and expect methods will be used to mock dependencies, such as external services and database queries, allowing each test to focus solely on the controller’s logic.
2. Analyze Test Coverage: Each test case will be assessed to ensure it covers critical functionality, focusing on edge cases, error handling, and user interactions. Validation, state transitions, flash messages, redirects, and boundary conditions will all be reviewed for completeness.
3. Run Tests Using RSpec: The test suite will be executed to verify expected outcomes, including flash messages, redirects, and state transitions.
4. Evaluate Outcomes:
- Success: Confirm that flash messages, redirects, and state transitions function as expected.
- Failure: Verify that errors and edge cases are handled gracefully, providing relevant feedback to the user.
Changes Made
- Old code
def add_reviewer
assignment = Assignment.find(params[:id])
topic_id = params[:topic_id]
user_id = User.where(name: params[:user][:name]).first.id
# If instructor want to assign one student to review his/her own artifact,
# it should be counted as "self-review" and we need to make /app/views/submitted_content/_selfreview.html.erb work.
if TeamsUser.exists?(team_id: params[:contributor_id], user_id: user_id)
flash[:error] = 'You cannot assign this student to review his/her own artifact.'
else
- New Modified code
#If reviewer is a participant of the assignment, then only move forward with reviewer assignment.
#Work Done: Refactored add_reviewer and extracted some code to make it smaller.
def add_reviewer
assignment = get_assignment(params[:id])
topic_id = params[:topic_id]
user_id = if User.where(name: params[:user][:name]).first
then User.where(name: params[:user][:name]).first.id
else nil
end
if user_id.nil?
flash[:error] = 'The user does not exist.'
redirect_to action: 'list_mappings', id: assignment.id, msg: 'The user does not exist.'
return
end
# If instructor wants to assign one student to review his/her own artifact,
# it should be counted as "self-review" and we need to make /app/views/submitted_content/_selfreview.html.erb work.
if check_for_self_review?(params[:contributor_id], user_id)
flash[:error] = 'You cannot assign this student to review his/her own artifact.'
redirect_to action: 'list_mappings', id: assignment.id
return
end
# Team lazy initialization
SignUpSheet.signup_team(assignment.id, user_id, topic_id)
- Code Added
# @param topic_id [Integer] The ID of the topic to be assigned
# @param assignment [Assignment] The current assignment
# @param reviewer [User] The reviewer being assigned
# @return [void] No result is returned
def assignment_with_topics(topic_id, assignment, reviewer)
topic = assign_topics_to_reviewer(topic_id, reviewer)
if topic.nil?
flash[:error] = 'No topics are available to review at this time. Please try later.'
else
assignment.assign_reviewer_dynamically(reviewer, topic)
end
end
- Code Added
#ADDED: Assigns team with no topic to reviewer dynamically
# @param assignment [Assignment] The current assignment
# @param reviewer [User] The reviewer being assigned
# @return [void] No result is returned
def assignment_with_no_topics(assignment, reviewer)
assignment_team = assign_team_to_review(assignment, reviewer)
if assignment_team.nil?
flash[:error] = 'No artifacts are available to review at this time. Please try later.'
else
assignment.assign_reviewer_dynamically_no_topic(reviewer, assignment_team)
end
end
- Old code
def delete_all_metareviewers
mapping = ResponseMap.find(params[:id])
mmappings = MetareviewResponseMap.where(reviewed_object_id: mapping.map_id)
num_unsuccessful_deletes = 0
mmappings.each do |mmapping|
begin
mmapping.delete(ActiveModel::Type::Boolean.new.cast(params[:force]))
rescue StandardError
num_unsuccessful_deletes += 1
end
end
- New Modified Code
# @param [Integer] params[:id] - ID of the ResponseMap whose metareview mappings need to be deleted.
# @param [Boolean] params[:force] - Flag to indicate if deletion should be forced despite existing dependencies.
# @output:
# - Success: "All metareview mappings for contributor X and reviewer Y have been deleted."
# - Failure: "A delete action failed: Z metareviews exist for these mappings. Options to delete them anyway."
# @output Redirects to the 'list_mappings' action for the assignment.
def delete_all_metareviewers
mapping = ResponseMap.find(params[:id])
meta_review_mappings = MetareviewResponseMap.where(reviewed_object_id: mapping.map_id)
unsuccessful_deletes_count = 0
meta_review_mappings.each do |meta_review_mappings|
begin
meta_review_mappings.delete(ActiveModel::Type::Boolean.new.cast(params[:force]))
rescue StandardError
unsuccessful_deletes_count += 1
end
end
- Code Added
#Added: Assigns a reviewer to a contributor (team or participant) in the context of an assignment
# @param user [User] The user being assigned as a reviewer.
# @param assignment [Assignment] The assignment to which the review is related.
# @param contributor_id [Integer] The ID of the contributor (team or participant) being reviewed.
# @param topic_id [Integer] The ID of the topic associated with the review (if applicable).
# @raise [RuntimeError] Raises an error if the reviewer is already assigned to the contributor.
# @return [ReviewResponseMap] The newly created review response mapping record.
def assign_reviewer_to_contributor(user, assignment, contributor_id, topic_id)
# Generate registration URL
reg_url = url_for id: assignment.id, user_id: user.id, contributor_id: contributor_id
# Get the assignment's participant corresponding to the user
reviewer = get_reviewer(user, assignment, reg_url)
# Check if reviewer is already assigned
if ReviewResponseMap.exists?(reviewee_id: contributor_id, reviewer_id: reviewer.id)
raise "The reviewer, \"#{reviewer.name}\", is already assigned to this contributor."
else
ReviewResponseMap.create(
reviewee_id: contributor_id,
reviewer_id: reviewer.id,
reviewed_object_id: assignment.id
)
end
end
- Code Added
#ADDED : Extracted the logic that decides whether to call assignment_with_topics or assignment_with_no_topics
# @param assignment [Assignment] The current assignment
# @param reviewer [User] The reviewer being assigned
# @return [void] No result is returned
def assign_reviewer_based_on_topics(assignment, reviewer)
if assignment.topics?# assignment with topics
assignment_with_topics(params[:topic_id], assignment, reviewer)
else
assignment_with_no_topics(assignment, reviewer)
end
end
Final Changes
Overview
Functions that were previously tightly coupled within the `ReviewMappingController` have been modularized and moved to a dedicated `ReviewMappingHelper` module. This change reduces code redundancy and ensures that the controller focuses solely on handling HTTP requests and responses, while the helper manages reusable logic.
Details
Functions Relocated:
Key utility functions that provide foundational functionality for the review mapping process have been moved to ReviewMappingHelper. These include:
- get_participant_or_reviewer: Fetches participant details if the user is added to the assignment.
- get_review_response_mapping: Retrieves review response mapping details for assigned reviewers.
- get_assignment: Fetches assignment information using its ID.
- check_for_self_review?: Checks if a user is attempting to review their own submission.
Centralization of Logic:
By centralizing these frequently used methods in a helper module:
- Future modifications to these functions only need to be made in one place, ensuring consistency across the application.
- Reusability is enhanced, as the same function can be utilized by multiple methods within the controller without duplication.
Example:
- The get_participant_or_reviewer function is now invoked in both the add_reviewer and assign_metareviewer_dynamically methods. This eliminates redundant logic and ensures the participant-fetching logic is uniform across all controller actions.
- In the old implementation, any changes to participant-fetching logic would require updating multiple methods in the controller. With the helper module, the change needs to be made only once, improving reliability and efficiency.
Inline Documentation with YARD-Style Comments Overview: Methods now include detailed YARD-style inline comments that provide structured documentation on parameters, return types, and exceptions. This serves as a valuable reference for developers, facilitating a quicker understanding of method behavior and usage.
Details:
YARD Documentation Structure:
Each method now includes:
- A clear description of its purpose.
- Definitions of all parameters with their data types and expected values.
- Return type, specifying the output of the method.
- Exceptions that may be raised, ensuring developers are aware of edge cases.
Example:
# Assigns a reviewer to a contributor (team or participant) in the context of an assignment.
# @param user [User] The user being assigned as a reviewer.
# @param assignment [Assignment] The assignment to which the review is related.
# @param contributor_id [Integer] The ID of the contributor (team or participant) being reviewed.
# @param topic_id [Integer] The ID of the topic associated with the review (if applicable).
# @raise [RuntimeError] Raises an error if the reviewer is already assigned to the contributor.
# @return [ReviewResponseMap] The newly created review response mapping record.
Improved Developer Experience:
- Developers can quickly understand how to use the method without needing to analyze its implementation.
- By clearly specifying edge cases and exceptions, the documentation encourages the correct use of the methods and reduces potential misuse.
- Ensures that future maintainers have a reliable source of truth for understanding how each function operates.
Benefit:
- Facilitates onboarding for new developers, reducing the learning curve.
- Serves as a self-contained guide for maintaining and extending the functionality of the module.
- Improves the quality of the codebase by encouraging thoughtful consideration of method responsibilities and error conditions.
Testing
1. Integration of ReviewMappingHelper
- Old Test: Utility functions such as get_participant_or_reviewer were not directly integrated into the test cases.
- New Test: The ReviewMappingHelper module is included in the test file, allowing direct access to its methods, enhancing modularity, and enabling focused testing of helper methods.
2. Use of Descriptive Doubles
- Old Test: Doubles were loosely defined with minimal attributes.
- Example:
let(:participant) { double('AssignmentParticipant', id: 1, can_review: false, user: double('User', id: 1)) }
- New Test: Doubles have been expanded to include attributes like user_id to better simulate real objects.
- Example:
let(:participant) { double('AssignmentParticipant', id: 1, user_id: 1, can_review: false, user: double('User', id: 1, user_id: 1)) }
- Benefit: Provides more accurate simulations of actual objects, leading to more reliable tests.
3. Improved Context Organization
- Old Test: Contexts were repetitive and not well-structured.
- Example: #add_reviewer and #get_reviewer grouped multiple sub-tests without isolating helper logic.
- New Test: Contexts are reorganized to test specific scenarios more effectively, focusing on helper methods and controller actions separately.
4. Additional Coverage for Flags
- Old Test: Did not account for scenarios like exclude_teams_without_submission.
- New Test: Includes tests for configuration flags to ensure that feature-specific conditions are tested, e.g.,:
context 'when exclude_teams_without_submission is enabled' do
it 'excludes teams without submissions and redirects to list_mappings'
end
5. Better Assertion Practices
- Old Test: Assertions primarily relied on verifying redirections and flash messages.
- New Test: Assertions now check assigned variables, method calls, and flash messages for deeper validation.
Example:
it 'finds the correct ResponseMap and assigns it to @mapping' do
expect(assigns(:mapping)).to eq(response_map)
end
Rspec Test

1. RSpec has been successfully used to test the ReviewMappingController, ensuring comprehensive coverage and reliability. All the examples have passed, demonstrating that the controller's functionality is working as expected. The tests are focused on validating key behaviors, error handling, and edge cases.

2. RSpec has been successfully applied to test the ReviewMappingHelper, ensuring the correctness and modularity of the helper methods. All test examples have passed, demonstrating that the helper functions perform as expected in various scenarios. The tests focus on ensuring the helper methods work seamlessly with the ReviewMappingController and other components.

3. RSpec has been successfully applied to test the entire controllers directory, ensuring that all controller actions across the application are thoroughly tested. All test examples have passed without breaking any functionality, confirming the reliability and robustness of the controllers.

4. All of the tests pass for expertiza. This is shown in the image above.
Team
Mentor
- Nainisha Bhallamudi
Members
- Gauri Verma
- Vaibhav Hawaldar
- Raj Kalantri