<?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=Akoul2</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=Akoul2"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Akoul2"/>
	<updated>2026-08-21T22:39:09Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160756</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160756"/>
		<updated>2024-12-04T05:37:45Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty string name. The response status is 201, with team name autogenerated.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman&lt;br /&gt;
*Scenario 1:&lt;br /&gt;
[[File:Akoul2Create.jpg]]&lt;br /&gt;
*Scenario 2:&lt;br /&gt;
[[File:Akoul2Create2.jpg]]&lt;br /&gt;
*Scenario 3:&lt;br /&gt;
[[File:Akoul2Create3.jpg]]&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
**[[File:Akoul2Update1.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Update2.jpg]]&lt;br /&gt;
**Scenario 3:&lt;br /&gt;
[[File:Akoul2Update3.jpg]]&lt;br /&gt;
**Scenario 4:&lt;br /&gt;
[[File:Akoul2Update4.jpg]]&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1: &lt;br /&gt;
[[File:2476_delete_1.png]]&lt;br /&gt;
&lt;br /&gt;
**Scenario 2: &lt;br /&gt;
[[File:2476_delete_2.png]]&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman:&lt;br /&gt;
[[File:Akoul2Add participant.jpg]]&lt;br /&gt;
&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160754</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160754"/>
		<updated>2024-12-04T05:36:38Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty string name. The response status is 201, with team name autogenerated.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman&lt;br /&gt;
*Scenario 1:&lt;br /&gt;
[[File:Akoul2Create.jpg]]&lt;br /&gt;
*Scenario 2:&lt;br /&gt;
[[File:Akoul2Create2.jpg]]&lt;br /&gt;
*Scenario 3:&lt;br /&gt;
[[File:Akoul2Create3.jpg]]&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
**[[File:Akoul2Update1.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Update2.jpg]]&lt;br /&gt;
**Scenario 3:&lt;br /&gt;
[[File:Akoul2Update3.jpg]]&lt;br /&gt;
**Scenario 4:&lt;br /&gt;
[[File:Akoul2Update4.jpg]]&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
*Scenario 1: [[File:2476_delete_1.png]]&lt;br /&gt;
*Scenario 2: [[File:2476_delete_2.png]]&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman:&lt;br /&gt;
[[File:Akoul2Add participant.jpg]]&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160747</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160747"/>
		<updated>2024-12-04T05:34:06Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty string name. The response status is 201, with team name autogenerated.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman&lt;br /&gt;
*Scenario 1:&lt;br /&gt;
[[File:Akoul2Create.jpg]]&lt;br /&gt;
*Scenario 2:&lt;br /&gt;
[[File:Akoul2Create2.jpg]]&lt;br /&gt;
*Scenario 3:&lt;br /&gt;
[[File:Akoul2Create3.jpg]]&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman&lt;br /&gt;
Scenario 1:&lt;br /&gt;
[[File:Akoul2Update1.jpg]]&lt;br /&gt;
Scenario 2:&lt;br /&gt;
[[File:Akoul2Update2.jpg]]&lt;br /&gt;
Scenario 3:&lt;br /&gt;
[[File:Akoul2Update3.jpg]]&lt;br /&gt;
Scenario 4:&lt;br /&gt;
[[File:Akoul2Update4.jpg]]&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
*Scenario 1: [[File:2476_delete_1.png]]&lt;br /&gt;
*Scenario 2: [[File:2476_delete_1.png]]&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman:&lt;br /&gt;
[[File:Akoul2Add participant.jpg]]&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update4.jpg&amp;diff=160746</id>
		<title>File:Akoul2Update4.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update4.jpg&amp;diff=160746"/>
		<updated>2024-12-04T05:33:09Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update3.jpg&amp;diff=160745</id>
		<title>File:Akoul2Update3.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update3.jpg&amp;diff=160745"/>
		<updated>2024-12-04T05:32:57Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update2.jpg&amp;diff=160744</id>
		<title>File:Akoul2Update2.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update2.jpg&amp;diff=160744"/>
		<updated>2024-12-04T05:32:49Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update1.jpg&amp;diff=160743</id>
		<title>File:Akoul2Update1.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Update1.jpg&amp;diff=160743"/>
		<updated>2024-12-04T05:32:35Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160735</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160735"/>
		<updated>2024-12-04T05:27:42Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty string name. The response status is 201, with team name autogenerated.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman&lt;br /&gt;
*Scenario 1:&lt;br /&gt;
[[File:Akoul2Create.jpg]]&lt;br /&gt;
*Scenario 2:&lt;br /&gt;
[[File:Akoul2Create2.jpg]]&lt;br /&gt;
*Scenario 3:&lt;br /&gt;
[[File:Akoul2Create3.jpg]]&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: [[File:2476_delete_1.png]]&lt;br /&gt;
*Scenario 2: [[File:2476_delete_1.png]]&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman:&lt;br /&gt;
[[File:Akoul2Add participant.jpg]]&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160733</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160733"/>
		<updated>2024-12-04T05:26:30Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty string name. The response status is 201, with team name autogenerated.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman&lt;br /&gt;
*Scenario 1:&lt;br /&gt;
[[File:Akoul2Create.jpg]]&lt;br /&gt;
*Scenario 2:&lt;br /&gt;
[[File:Akoul2Create2.jpg]]&lt;br /&gt;
*Scenario 3:&lt;br /&gt;
[[File:Akoul2Create3.jpg]]&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman:&lt;br /&gt;
[[File:Akoul2Add participant.jpg]]&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160731</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160731"/>
		<updated>2024-12-04T05:26:02Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty string name. The response status is 201, with team name autogenerated.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman&lt;br /&gt;
Scenario 1:&lt;br /&gt;
[[File:Akoul2Create.jpg]]&lt;br /&gt;
Scenario 2:&lt;br /&gt;
[[File:Akoul2Create2.jpg]]&lt;br /&gt;
Scenario 3:&lt;br /&gt;
[[File:Akoul2Create3.jpg]]&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman:&lt;br /&gt;
[[File:Akoul2Add participant.jpg]]&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Create3.jpg&amp;diff=160727</id>
		<title>File:Akoul2Create3.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Create3.jpg&amp;diff=160727"/>
		<updated>2024-12-04T05:21:24Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Create2.jpg&amp;diff=160726</id>
		<title>File:Akoul2Create2.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Create2.jpg&amp;diff=160726"/>
		<updated>2024-12-04T05:21:00Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Create.jpg&amp;diff=160724</id>
		<title>File:Akoul2Create.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Create.jpg&amp;diff=160724"/>
		<updated>2024-12-04T05:20:49Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160718</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160718"/>
		<updated>2024-12-04T05:17:49Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty name. The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
*Postman:&lt;br /&gt;
[[File:Akoul2Add participant.jpg]]&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Add_participant.jpg&amp;diff=160717</id>
		<title>File:Akoul2Add participant.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Add_participant.jpg&amp;diff=160717"/>
		<updated>2024-12-04T05:17:41Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160714</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160714"/>
		<updated>2024-12-04T05:12:09Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty name. The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
*Postman:&lt;br /&gt;
**Scenario 1:&lt;br /&gt;
[[File:Akoul2Show.jpg]]&lt;br /&gt;
**Scenario 2:&lt;br /&gt;
[[File:Akoul2Show not.jpg]]&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Show_not.jpg&amp;diff=160712</id>
		<title>File:Akoul2Show not.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Show_not.jpg&amp;diff=160712"/>
		<updated>2024-12-04T05:09:52Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160705</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160705"/>
		<updated>2024-12-04T05:06:56Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Added Index Postman */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
*Postman Screenshot&lt;br /&gt;
[[File:Akoul2Index.jpg]]&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty name. The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Show.jpg&amp;diff=160703</id>
		<title>File:Akoul2Show.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Show.jpg&amp;diff=160703"/>
		<updated>2024-12-04T05:01:48Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Index.jpg&amp;diff=160701</id>
		<title>File:Akoul2Index.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Index.jpg&amp;diff=160701"/>
		<updated>2024-12-04T05:01:37Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Delete.jpg&amp;diff=160700</id>
		<title>File:Akoul2Delete.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Akoul2Delete.jpg&amp;diff=160700"/>
		<updated>2024-12-04T05:01:22Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Create.jpg&amp;diff=160698</id>
		<title>File:Create.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Create.jpg&amp;diff=160698"/>
		<updated>2024-12-04T05:00:09Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: Akoul2 uploaded a new version of File:Create.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160675</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160675"/>
		<updated>2024-12-04T04:48:59Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Tasks Completed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
** index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
** show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
** create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
** update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
** destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
** remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
** add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty name. The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160674</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160674"/>
		<updated>2024-12-04T04:48:43Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Tasks Completed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
* Controller - StudentTeamsController.rb&lt;br /&gt;
* index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
* show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
* create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
* update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
* destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
* remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
* add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty name. The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160671</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160671"/>
		<updated>2024-12-04T04:46:07Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
Controller - StudentTeamsController.rb&lt;br /&gt;
* index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
* show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
* create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
* update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
* destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
* remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
* add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Expectation: Successfully retrieves a list of all student teams. The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty name. The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160669</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160669"/>
		<updated>2024-12-04T04:44:13Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
Controller - StudentTeamsController.rb&lt;br /&gt;
* index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
* show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
* create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
* update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
* destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
* remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
* add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Successfully retrieves a list of all student teams.&lt;br /&gt;
*Expectation: The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Expectation: Successfully creates a new student team with a valid name and student ID. The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Expectation: Attempts to create a student team with an empty name. The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Expectation: Successfully retrieves the details of a student team by its ID. The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to retrieve the details of a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Expectation: Successfully deletes a student team by its ID. The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to delete a student team with an invalid ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
*Description: Add a participant to a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully add a participant to a student team&lt;br /&gt;
*Expectation: Successfully adds a participant to a student team by their ID. The response status is 200, and the participant is added to the team.&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
*Description: Remove a participant from a student team.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Successfully remove a participant from a student team&lt;br /&gt;
*Expectation: Successfully removes a participant from a student team by their ID. The response status is 204, and the participant is no longer a member of the team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
*Scenario 3: User not found &lt;br /&gt;
*Expectation: Attempts to remove a participant from a student team with an invalid user ID. The response status is 404, and the response body includes an error message indicating that the user was not found.&lt;br /&gt;
&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Demo Video===&lt;br /&gt;
&lt;br /&gt;
https://www.youtube.com/watch?v=8_d_Y9EcgHc&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160657</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160657"/>
		<updated>2024-12-04T04:34:09Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
Controller - StudentTeamsController.rb&lt;br /&gt;
* index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
* show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
* create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
* update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
* destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
* remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
* add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Description: Successfully retrieves a list of all student teams.&lt;br /&gt;
*Expectation: The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*2.1 Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
2.2 Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Description: Successfully creates a new student team with a valid name and student ID.&lt;br /&gt;
*Expectation: The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Description: Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Description: Attempts to create a student team with an empty name.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
*Description: Update the details of a student team.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Scenarios:&lt;br /&gt;
*Scenario 1: Team name updated successfully&lt;br /&gt;
*Expectation: Successfully updates the name of a student team. The response status is 200, and the response body includes the updated team name.&lt;br /&gt;
*Scenario 2: Invalid team update (empty name)&lt;br /&gt;
*Expectation: Attempts to update a student team with an empty name. The response status is 422, and the response body includes an error message indicating that the team name should not be empty.&lt;br /&gt;
*Scenario 3: Team name already in use&lt;br /&gt;
*Expectation: Attempts to update a student team with a name that is already in use. The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 4: Invalid team ID&lt;br /&gt;
*Expectation: Attempts to update a student team with a non-existent team ID. The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
*Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*4.1 Test Case Scenarios:&lt;br /&gt;
*Scenario 1: Show Student Team&lt;br /&gt;
*Description: Successfully retrieves the details of a student team by its ID.&lt;br /&gt;
*Expectation: The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Description: Attempts to retrieve the details of a student team with an invalid ID.&lt;br /&gt;
*Expectation: The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
*Description: Delete a student team by its ID.&lt;br /&gt;
*Response: 204 No Content&lt;br /&gt;
*5.1 Scenarios:&lt;br /&gt;
*Scenario 1: Successfully delete a student team&lt;br /&gt;
*Description: Successfully deletes a student team by its ID.&lt;br /&gt;
*Expectation: The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
*Scenario 2: Team not found&lt;br /&gt;
*Description: Attempts to delete a student team with an invalid ID.&lt;br /&gt;
*Expectation: The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
6.1 Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
6.2 Scenarios:&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
7.1 Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
Scenarios:&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160652</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160652"/>
		<updated>2024-12-04T04:21:21Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
Controller - StudentTeamsController.rb&lt;br /&gt;
* index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
* show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
* create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
* update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
* destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
* remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
* add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
*Description: List all student teams.&lt;br /&gt;
*Response: 200 OK&lt;br /&gt;
*Test Case Scenarios:&lt;br /&gt;
*Scenario 1: List all Student Teams&lt;br /&gt;
*Description: Successfully retrieves a list of all student teams.&lt;br /&gt;
*Expectation: The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
*Description: Create a new student team.&lt;br /&gt;
*Response: 201 Created&lt;br /&gt;
*2.1 Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
2.2 Scenarios:&lt;br /&gt;
*Scenario 1: Successfully create a team&lt;br /&gt;
*Description: Successfully creates a new student team with a valid name and student ID.&lt;br /&gt;
*Expectation: The response status is 201, and the response body includes the team name.&lt;br /&gt;
*Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
*Description: Attempts to create a student team with a name that is already in use.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
*Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
*Description: Attempts to create a student team with an empty name.&lt;br /&gt;
*Expectation: The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
Description: Update the details of a student team.&lt;br /&gt;
Response: 200 OK&lt;br /&gt;
Test Case Scenarios:&lt;br /&gt;
Scenario 1: Update Student Team&lt;br /&gt;
Description: Successfully updates the details of a student team.&lt;br /&gt;
Expectation: The response status is 200, and the response body includes the updated details of the student team.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
Response: 200 OK&lt;br /&gt;
4.1 Test Case Scenarios:&lt;br /&gt;
Scenario 1: Show Student Team&lt;br /&gt;
Description: Successfully retrieves the details of a student team by its ID.&lt;br /&gt;
Expectation: The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
Scenario 2: Team not found&lt;br /&gt;
Description: Attempts to retrieve the details of a student team with an invalid ID.&lt;br /&gt;
Expectation: The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
Description: Delete a student team by its ID.&lt;br /&gt;
Response: 204 No Content&lt;br /&gt;
5.1 Scenarios:&lt;br /&gt;
Scenario 1: Successfully delete a student team&lt;br /&gt;
Description: Successfully deletes a student team by its ID.&lt;br /&gt;
Expectation: The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
Scenario 2: Team not found&lt;br /&gt;
Description: Attempts to delete a student team with an invalid ID.&lt;br /&gt;
Expectation: The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
6.1 Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
6.2 Scenarios:&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
7.1 Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
Scenarios:&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===GitHub Pull Request===&lt;br /&gt;
&lt;br /&gt;
https://github.com/expertiza/reimplementation-back-end/pull/136&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160650</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160650"/>
		<updated>2024-12-04T04:20:19Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
Files Modified:&lt;br /&gt;
* Created ==&amp;gt;&lt;br /&gt;
** app/controllers/api/v1/student_teams_controller.rb&lt;br /&gt;
** app/models/assignment_team.rb&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** spec/requests/api/v1/student_teams_controller_spec.rb&lt;br /&gt;
** db/migrate/20241201203840_create_assignment_teams.rb&lt;br /&gt;
** db/migrate/20241201220020_add_auto_assign_mentor_to_assignments.rb&lt;br /&gt;
** db/migrate/20241201221122_add_type_to_teams.rb&lt;br /&gt;
** db/migrate/20241202002102_add_name_to_teams.rb&lt;br /&gt;
&lt;br /&gt;
* Updated ==&amp;gt;&lt;br /&gt;
** app/models/team.rb&lt;br /&gt;
** config/routes.rb&lt;br /&gt;
** db/schema.rb&lt;br /&gt;
** db/seeds.rb&lt;br /&gt;
** spec/swagger_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Tasks Completed===&lt;br /&gt;
&lt;br /&gt;
Methods:&lt;br /&gt;
* AssignmentTeam Model:&lt;br /&gt;
** To access every participant connected to an assignment, the assignment_participants method was added.&lt;br /&gt;
** For including a user in the assignment as a participant, the add_participant method was added.&lt;br /&gt;
** To see if the team has gotten any peer reviews, the received_any_peer_review? method was put into practice.&lt;br /&gt;
** Using a placeholder for future mentor assignment logic, the upgrade_to_mentored_team method was put into practice to replicate the present team and get it ready for mentoring.&lt;br /&gt;
** In order to ensure deep duplication of associated records (such as signed_up_teams, teams_users, and participants), the dup method was added to duplicate a team and its associations.&lt;br /&gt;
&lt;br /&gt;
* Team Model:&lt;br /&gt;
** Improved the whole procedure to determine if a team has reached its maximum number of members.&lt;br /&gt;
** Counted the number of team members using the size approach, removing those with &amp;quot;(Mentor)&amp;quot; in their names.&lt;br /&gt;
** In order to eliminate duplicate members and check for team capacity, the add_member method was improved.&lt;br /&gt;
** To remove a user from the team, the remove_team_user method was put into place. If the team becomes empty and hasn't been subjected to any peer reviews, the team will be deleted.&lt;br /&gt;
&lt;br /&gt;
Controller - StudentTeamsController.rb&lt;br /&gt;
* index: Implemented in order to retrieve and restore every student team together with all of its members.&lt;br /&gt;
* show: Created to retrieve and provide information about a certain student team and its members.&lt;br /&gt;
* create: Added logic to create a new team for a student, using AssignmentTeam#upgraded_to_mentored_team for mentor-eligible teams and checking for existing team names.&lt;br /&gt;
* update: Implemented to enable team details, especially the team name, to be updated while ensuring unique team names through validations.&lt;br /&gt;
* destroy: To remove a certain team this was added and, if successful, deliver a 204 No Content response.&lt;br /&gt;
* remove_participant: Check if the user is part of the given team and removes from that team, also handles corner cases where no more participants are there in a team.&lt;br /&gt;
* add_participant: Added this to add the given participant to respective team.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
&lt;br /&gt;
 Description: List all student teams.&lt;br /&gt;
 Response: 200 OK&lt;br /&gt;
 Test Case Scenarios:&lt;br /&gt;
 Scenario 1: List all Student Teams&lt;br /&gt;
 Description: Successfully retrieves a list of all student teams.&lt;br /&gt;
 Expectation: The response status is 200, the content type is `application/json`, and the response body contains 3 student teams.&lt;br /&gt;
&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
Description: Create a new student team.&lt;br /&gt;
Response: 201 Created&lt;br /&gt;
2.1 Test Data prep:&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
2.2 Scenarios:&lt;br /&gt;
Scenario 1: Successfully create a team&lt;br /&gt;
Description: Successfully creates a new student team with a valid name and student ID.&lt;br /&gt;
Expectation: The response status is 201, and the response body includes the team name.&lt;br /&gt;
Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
Description: Attempts to create a student team with a name that is already in use.&lt;br /&gt;
Expectation: The response status is 422, and the response body includes an error message indicating that the team name is already in use.&lt;br /&gt;
Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
Description: Attempts to create a student team with an empty name.&lt;br /&gt;
Expectation: The response status is 422, and the response body includes an error message.&lt;br /&gt;
&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
Description: Update the details of a student team.&lt;br /&gt;
Response: 200 OK&lt;br /&gt;
Test Case Scenarios:&lt;br /&gt;
Scenario 1: Update Student Team&lt;br /&gt;
Description: Successfully updates the details of a student team.&lt;br /&gt;
Expectation: The response status is 200, and the response body includes the updated details of the student team.&lt;br /&gt;
&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
Description: Retrieve the details of a student team by its ID.&lt;br /&gt;
Response: 200 OK&lt;br /&gt;
4.1 Test Case Scenarios:&lt;br /&gt;
Scenario 1: Show Student Team&lt;br /&gt;
Description: Successfully retrieves the details of a student team by its ID.&lt;br /&gt;
Expectation: The response status is 200, and the response body includes the details of the student team.&lt;br /&gt;
Scenario 2: Team not found&lt;br /&gt;
Description: Attempts to retrieve the details of a student team with an invalid ID.&lt;br /&gt;
Expectation: The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
Description: Delete a student team by its ID.&lt;br /&gt;
Response: 204 No Content&lt;br /&gt;
5.1 Scenarios:&lt;br /&gt;
Scenario 1: Successfully delete a student team&lt;br /&gt;
Description: Successfully deletes a student team by its ID.&lt;br /&gt;
Expectation: The response status is 204, and the student team is no longer present in the database.&lt;br /&gt;
Scenario 2: Team not found&lt;br /&gt;
Description: Attempts to delete a student team with an invalid ID.&lt;br /&gt;
Expectation: The response status is 404, and the response body includes an error message indicating that the team was not found.&lt;br /&gt;
&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
6.1 Test Data Prep&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
6.2 Scenarios:&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
7.1 Test data prep:&lt;br /&gt;
&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
Scenarios:&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160579</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160579"/>
		<updated>2024-12-04T03:45:23Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
  post 'Create a Student Team' do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      let(:institution) do&lt;br /&gt;
        Institution.create!(&lt;br /&gt;
          name: 'North Carolina State University'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:instructor_role) { Role.find_or_create_by(name: 'Instructor') }&lt;br /&gt;
      let!(:student_role) { Role.find_or_create_by(name: 'Student') }&lt;br /&gt;
      let(:instructor_user) do&lt;br /&gt;
        User.create!(&lt;br /&gt;
          name: 'Dr. Ed Gehringer1',&lt;br /&gt;
          email: 'gehringer@example.com',&lt;br /&gt;
          password: 'password123',&lt;br /&gt;
          full_name: 'admin admin',&lt;br /&gt;
          institution_id: institution.id,&lt;br /&gt;
          role_id: instructor_role.id,&lt;br /&gt;
          handle: 'instructor'&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:course) do&lt;br /&gt;
        Course.create!(&lt;br /&gt;
          name: '2476. Refactor',&lt;br /&gt;
          directory_path: '/',&lt;br /&gt;
          info: 'OODD',&lt;br /&gt;
          private: false,&lt;br /&gt;
          instructor_id: instructor_user.id,&lt;br /&gt;
          institution_id: institution.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let(:assignment) do&lt;br /&gt;
        Assignment.create!(&lt;br /&gt;
          title: 'Project 4 BRO',&lt;br /&gt;
          description: '2476. Reimplementing',&lt;br /&gt;
          course_id: course.id,&lt;br /&gt;
          instructor_id: instructor_user.id&lt;br /&gt;
        )&lt;br /&gt;
      end&lt;br /&gt;
      let!(:students) do&lt;br /&gt;
        created_students = []&lt;br /&gt;
        3.times do |i|&lt;br /&gt;
          student = User.create!(&lt;br /&gt;
            name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            email: &amp;quot;Student#{i + 1}@gmail.com&amp;quot;,&lt;br /&gt;
            password: 'password123',&lt;br /&gt;
            full_name: &amp;quot;Student #{i + 1}&amp;quot;,&lt;br /&gt;
            institution_id: institution.id,&lt;br /&gt;
            role_id: student_role.id,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          AssignmentParticipant.create!(&lt;br /&gt;
            assignment: assignment,&lt;br /&gt;
            user: student,&lt;br /&gt;
            handle: &amp;quot;Student #{i + 1}&amp;quot;&lt;br /&gt;
          )&lt;br /&gt;
          created_students &amp;lt;&amp;lt; student&lt;br /&gt;
        end&lt;br /&gt;
        created_students&lt;br /&gt;
      end&lt;br /&gt;
    &lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          student_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # Scenario 1: Successfully create a team&lt;br /&gt;
      response(201, 'created') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;HelloThere&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(201)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Team name is already in use (conflict)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', assignment_id: assignment.id) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: students.first.id }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Invalid team creation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, student_id: students.first.id}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('error')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, student_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
  patch('Update a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      parameter name: :student_team_request, in: :body, schema: {&lt;br /&gt;
        type: :object,&lt;br /&gt;
        properties: {&lt;br /&gt;
          team: {&lt;br /&gt;
            type: :object,&lt;br /&gt;
            properties: {&lt;br /&gt;
              name: {type: :string}&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          team_id: { type: :integer}&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      # Scenario 1: Team name updated successfully&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 2: Invalid team updation (empty name)&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:student_team_request) do&lt;br /&gt;
          { team: {name: &amp;quot;&amp;quot;}, team_id: 2}&lt;br /&gt;
        end&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('Team name should not be empty')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Scenario 3: Team Name already present&lt;br /&gt;
      response(422, 'unprocessable entity') do&lt;br /&gt;
        let(:existing_team) { create(:team, name: 'ABCD10', team_id: 3) }&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 2 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(422)&lt;br /&gt;
          expect(response.body).to include('&amp;quot;error&amp;quot;:&amp;quot;That team name is already in use.&amp;quot;')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      #Scenario 4 : Invalid Team ID&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:team) do&lt;br /&gt;
          post '/api/v1/student_teams', params: { team: { name: 'ABCD10' }, team_id: 0 }, as: :json&lt;br /&gt;
        end&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
            expect(response.body).to include('not found')&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
  path '/api/v1/student_teams/{id}' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer&lt;br /&gt;
    # Get request on /api/v1/student_teams/{id} returns the response 200 succesful - when correct id passed is present in the database&lt;br /&gt;
    get('Show a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(200)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # Get request on /api/v1/student_teams/{id} returns the response 404 not found - when correct id passed is not present in the database&lt;br /&gt;
      response(404, 'not_found') do&lt;br /&gt;
        let(:id) { 'invalid' }&lt;br /&gt;
          run_test! do&lt;br /&gt;
            expect(response.status).to eq(404)&lt;br /&gt;
          end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
  delete('Delete a Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 204 succesful response when id present in the database is deleted successfully&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: ''&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      # delete request on /api/v1/student_teams/{id} returns 404 not found response, when id is not present in the database&lt;br /&gt;
      response(404, 'not found') do&lt;br /&gt;
        let(:id) { 0 }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
  path '/api/v1/student_teams/{id}/add_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    patch('Add a participant to Student Team') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      consumes 'application/json'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      before do&lt;br /&gt;
        team.add_member(student, assignment.id)&lt;br /&gt;
      end&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test! &lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
  path '/api/v1/student_teams/{id}/remove_participant' do&lt;br /&gt;
    parameter name: 'id', in: :path, type: :integer, description: 'ID of Team'&lt;br /&gt;
    parameter name: 'student_id', in: :query, type: :integer, description: 'ID of the Student'&lt;br /&gt;
    let(:student) { create(:user, :student) }&lt;br /&gt;
    let(:assignment) { create(:assignment) }&lt;br /&gt;
    let(:student_participant) { create(:assignment_participant, user: student, assignment: assignment) }&lt;br /&gt;
    let(:team) { create(:assignment_team, assignment: assignment) }&lt;br /&gt;
    let(:id) { team.id }&lt;br /&gt;
    let(:student_id) { student.id }&lt;br /&gt;
    before do&lt;br /&gt;
      team.add_member(student, assignment.id)&lt;br /&gt;
    end&lt;br /&gt;
    delete('remove participant') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(204, 'successful') do&lt;br /&gt;
        let(:Authorization) { &amp;quot;Bearer #{@token}&amp;quot; }&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(204)&lt;br /&gt;
          expect(team.members).not_to include(student)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'team not found') do&lt;br /&gt;
        let(:id) { -1 } # Invalid ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('Team not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      response(404, 'user not found') do&lt;br /&gt;
        let(:student_id) { -1 } # Invalid student ID&lt;br /&gt;
        run_test! do&lt;br /&gt;
          expect(response.status).to eq(404)&lt;br /&gt;
          expect(JSON.parse(response.body)['error']).to eq('User not found.')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160565</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=160565"/>
		<updated>2024-12-04T03:40:26Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Adding All Testing Plans */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Introduction===&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is an open-source system built on [http://rubyonrails.org/ Ruby on Rails], collaboratively maintained by students and faculty at NC State. This platform gives instructors extensive control over assignments, enabling them to add topics, create assignment groups, and manage peer reviews for various types of coursework. Expertiza is well-equipped to handle submissions across multiple formats, including URLs and wiki pages, and it offers a peer review system that facilitates constructive feedback among students.&lt;br /&gt;
&lt;br /&gt;
A key focus of recent development in Expertiza has been the shift to a client-server architecture, where Ruby on Rails functions as the backend and React is utilized for the frontend. This architectural update requires reworking existing modules into RESTful API endpoints, allowing React components to interact efficiently with the backend. By adopting this approach, Expertiza aims to enhance modularity, performance, and scalability.&lt;br /&gt;
&lt;br /&gt;
===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focuses on reimplementing the StudentTeamsController in Expertiza's backend, which is designed for student-facing operations where students participate in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
&lt;br /&gt;
The TeamsController, on the other hand, is focused on instructor-driven operations that handle high-level team management across different contexts, such as courses and assignments. It manages operations like team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP). For example, it also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic.&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
The main objective is to migrate the Student Task controller logic from serving HTML responses in the Ruby on Rails MVC model to returning JSON responses as a RESTful API, as part of the backend implementation. While reimplementing the controller, the following considerations will be incorporated to ensure a clean, maintainable, and scalable API:&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
[[File:2476_UML.drawio.png]]&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We have performed comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and Swagger to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell. &lt;br /&gt;
Below are the test scenarios for each of API endpoints - &lt;br /&gt;
&lt;br /&gt;
1. List all Student Teams&lt;br /&gt;
 RSpec.describe 'Student Teams API', type: :request do&lt;br /&gt;
 path '/api/v1/student_teams' do&lt;br /&gt;
    # List all Student Teams&lt;br /&gt;
    get('List all Student Teams') do&lt;br /&gt;
      tags 'Student Teams'&lt;br /&gt;
      produces 'application/json'&lt;br /&gt;
      security [Bearer: {}]&lt;br /&gt;
      response(200, 'successful') do&lt;br /&gt;
        after do |example|&lt;br /&gt;
          example.metadata[:response][:content] = {&lt;br /&gt;
            'application/json' =&amp;gt; {&lt;br /&gt;
              example: JSON.parse(response.body, symbolize_names: true)&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        end&lt;br /&gt;
        run_test!&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
2. Create a Student Team&lt;br /&gt;
&lt;br /&gt;
3. Update a Student Team&lt;br /&gt;
&lt;br /&gt;
4. Show a Student Team&lt;br /&gt;
&lt;br /&gt;
5. Delete a Student Team&lt;br /&gt;
&lt;br /&gt;
6. Add a Participant in Student Team&lt;br /&gt;
&lt;br /&gt;
7. Remove a Participant in Student Team&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159142</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159142"/>
		<updated>2024-11-12T21:00:42Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focusses on reimplementing StudentTeamsController that is designed for student-facing operations where students are participants in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
TeamsController is focused on instructor-driven operations that deal with the high-level management of teams across different contexts like courses and assignments. It handles operations such as team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP).&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users and ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We plan to perform comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and leverage FactoryBot to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell.&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159141</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159141"/>
		<updated>2024-11-12T21:00:07Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: minor update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focusses on reimplementing StudentTeamsController that is designed for student-facing operations where students are participants in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
TeamsController is focused on instructor-driven operations that deal with the high-level management of teams across different contexts like courses and assignments. It handles operations such as team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP).&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users:&lt;br /&gt;
Ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We plan to perform comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and leverage FactoryBot to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell.&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159140</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159140"/>
		<updated>2024-11-12T20:46:19Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Problem Statement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focusses on reimplementing StudentTeamsController that is designed for student-facing operations where students are participants in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
TeamsController is focused on instructor-driven operations that deal with the high-level management of teams across different contexts like courses and assignments. It handles operations such as team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP).&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems create a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to reimplement the StudentTeamsController in the newer Expertiza backend codebase by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users:&lt;br /&gt;
Ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles &lt;br /&gt;
HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific &lt;br /&gt;
like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We plan to perform comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and leverage FactoryBot to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell.&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159139</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159139"/>
		<updated>2024-11-12T20:38:10Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Functionality */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focusses on reimplementing StudentTeamsController that is designed for student-facing operations where students are participants in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
TeamsController is focused on instructor-driven operations that deal with the high-level management of teams across different contexts like courses and assignments. It handles operations such as team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The current implementation of the StudentTeamsController in the Expertiza system is overly complex and tightly coupled, leading to difficulties in maintaining and extending the codebase. The controller is responsible for managing student teams in assignments, handling tasks like team creation, editing, management, and the integration of topics in assignments that require team-based decisions. However, it suffers from issues such as:&lt;br /&gt;
* Code redundancy and inefficiency due to business logic being embedded directly in the controller.&lt;br /&gt;
* Lack of modularity and poor separation of concerns, violating the Single Responsibility Principle (SRP).&lt;br /&gt;
* Difficult-to-understand methods and tightly coupled logic for handling assignment-specific conditions, such as team-topic associations.&lt;br /&gt;
* Poor user feedback that does not provide clear or actionable information after critical operations.&lt;br /&gt;
&lt;br /&gt;
These problems creates a system that is hard to scale, maintain, and extend, especially as new features are added. To address these challenges, the goal is to refactor the StudentTeamsController by adhering to object-oriented design principles, specifically focusing on maintainability, scalability, and modularity. The new design will improve the user experience by simplifying controller logic, providing clearer feedback, and ensuring that the system is easier to extend and maintain in the future.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users:&lt;br /&gt;
Ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
1. Reimplement the Controller to Follow SRP:&lt;br /&gt;
* Break down large, complex methods into smaller, focused methods that adhere to the Single Responsibility Principle (SRP).&lt;br /&gt;
* Reimplement existing methods and logic while ensuring that each class and method have a clear, well-defined responsibility.&lt;br /&gt;
* Move business logic and complex operations out of the controller and into the appropriate model classes (e.g., Team, AssignmentTeam), ensuring the controller only handles &lt;br /&gt;
HTTP-specific concerns (e.g., request handling, responses).&lt;br /&gt;
&lt;br /&gt;
2. Improve Method Naming and Clarity:&lt;br /&gt;
* Ensure all method names are descriptive and represent the intent of the operation (e.g., renaming methods like student_team_requirements_met? to something more specific &lt;br /&gt;
like validate_topic_requirements_for_team_creation).&lt;br /&gt;
* Adopt consistent naming conventions to improve the readability of the codebase.&lt;br /&gt;
&lt;br /&gt;
3. Implement the Prototype Pattern for Team Creation:&lt;br /&gt;
* Leverage the Prototype pattern to create mentored teams through the AssignmentTeam class, allowing for easier management and creation of teams with a mentored structure.&lt;br /&gt;
* Automatically generate team names when a team is first created, unless a user has specified a custom name to improve the user experience and simplify team management.&lt;br /&gt;
&lt;br /&gt;
4. Abstract Assignment-Specific Logic:&lt;br /&gt;
* Move logic related to assignment-specific requirements (e.g., topic handling) away from the controller, reducing complexity and increasing modularity.&lt;br /&gt;
* Introduce service objects or model methods to handle specific requirements like topic assignment, thereby decoupling assignment-related logic from the controller.&lt;br /&gt;
* Break down the student_team_requirements_met? method into smaller, more specific checks for different requirements (e.g., topic validation, minimum team size, etc.).&lt;br /&gt;
&lt;br /&gt;
5. Improve User Feedback:&lt;br /&gt;
* Enhance the clarity and actionability of feedback messages after key operations (e.g., team creation, user removal, etc.).&lt;br /&gt;
* Provide users with clear, helpful notifications on the success or failure of their actions, including any necessary next steps or troubleshooting guidance.&lt;br /&gt;
* Ensure error handling is robust, and feedback is specific (e.g., specify which conditions were not met when creating or modifying teams).&lt;br /&gt;
&lt;br /&gt;
6. Commenting and Documentation:&lt;br /&gt;
* Add comprehensive comments throughout the controller to clearly explain the purpose and functionality of custom methods and refactored logic.&lt;br /&gt;
* Ensure that code is well-documented, making it easier for future developers to understand and extend the functionality of the controller.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We plan to perform comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and leverage FactoryBot to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell.&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh Manoj            &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159046</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159046"/>
		<updated>2024-11-12T06:34:17Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Development Strategy */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focusses on reimplementing StudentTeamsController that is designed for student-facing operations where students are participants in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
TeamsController is focused on instructor-driven operations that deal with the high-level management of teams across different contexts like courses and assignments. It handles operations such as team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The problem statement provides the notion of reimplementing the StudentTeamsController to redesigning the new back-end code for Expertiza. The aim is to improve the code quality by adhering to object-oriented design principles and improving maintainability and scalability. The main focus is to eliminate code redundancy, ensure efficient handling of edge cases, and restructure methods so that they are placed appropriately in the respective classes.&lt;br /&gt;
The StudentTeamsController manages teams in student assignments, allowing users to create, edit, and manage teams for assignments. It also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic. The design of this logic should prioritize interactions that are user-facing, easy to understand and maintainable. By reimplementing this controller, the project aims to streamline its functionality and improving the code's overall efficiency and modularity.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users:&lt;br /&gt;
Ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
In the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase.&lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users:&lt;br /&gt;
Ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We plan to perform comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and leverage FactoryBot to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell.&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159045</id>
		<title>CSC/ECE 517 Fall 2024 - E2476. Reimplement student teams controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2476._Reimplement_student_teams_controller.rb&amp;diff=159045"/>
		<updated>2024-11-12T06:34:04Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: First draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Project Description===&lt;br /&gt;
&lt;br /&gt;
The project mainly focusses on reimplementing StudentTeamsController that is designed for student-facing operations where students are participants in teams. This includes actions that directly affect individual team members, such as adding or removing students from teams, viewing team details, and managing their participation.&lt;br /&gt;
TeamsController is focused on instructor-driven operations that deal with the high-level management of teams across different contexts like courses and assignments. It handles operations such as team creation, deletion, randomization, and bulk management actions.&lt;br /&gt;
&lt;br /&gt;
===Problem Statement===&lt;br /&gt;
&lt;br /&gt;
The problem statement provides the notion of reimplementing the StudentTeamsController to redesigning the new back-end code for Expertiza. The aim is to improve the code quality by adhering to object-oriented design principles and improving maintainability and scalability. The main focus is to eliminate code redundancy, ensure efficient handling of edge cases, and restructure methods so that they are placed appropriately in the respective classes.&lt;br /&gt;
The StudentTeamsController manages teams in student assignments, allowing users to create, edit, and manage teams for assignments. It also handles the integration with topics when assignments involve choosing topics, complicating the team’s logic. The design of this logic should prioritize interactions that are user-facing, easy to understand and maintainable. By reimplementing this controller, the project aims to streamline its functionality and improving the code's overall efficiency and modularity.&lt;br /&gt;
&lt;br /&gt;
===Objectives===&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users:&lt;br /&gt;
Ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Development Strategy===&lt;br /&gt;
&lt;br /&gt;
Our development strategy centers around Test-Driven Development (TDD) principles applied to refactoring the student_teams_controller.rb and other related classes such as Team or AssignmentTeam model. We design out test cases and iteratively refactor code to address identified inefficiencies while ensuring successful test outcomes.&lt;br /&gt;
Additionally, we emphasize on the strict adoption of SRP and DRY principles as per the object-oriented programming conventions. Our goal is to reimplement the existing functionalities &lt;br /&gt;
 in the newly designed back-end foundation to foster a more efficient and organized codebase utilizing newer technologies. This approach will significantly enhance reusability and scalability across all the application while maintaining clean codebase. &lt;br /&gt;
&lt;br /&gt;
===Project Design and Implementation===&lt;br /&gt;
&lt;br /&gt;
The main approach to be followed throughout this project is to embrace the Prototyping Pattern within the controller while taking into account the current functionalities to be reimplemented within the student_teams_controller.rb that can capitalize its capability to encapsulate distinct controller actions. This strategic implementation aims to ensure seamless extensibility and enhanced usability. By employing this pattern, we establish a structured framework for defining and managing the diverse operations the controller handles, promoting a more organized and manageable code structure.&lt;br /&gt;
&lt;br /&gt;
==== Functionality ====&lt;br /&gt;
&lt;br /&gt;
*Reimplement the controller logic and write methods which appropriately follow the Single Responsibility Principle (SRP).&lt;br /&gt;
*Move business logic from the controller to appropriate model classes like Team or AssignmentTeam.&lt;br /&gt;
*Ensure all method names clearly describe their purpose and represent actions. &lt;br /&gt;
*Reimplement a Prototype pattern for creating mentored teams, leveraging the AssignmentTeam class.&lt;br /&gt;
*Automatically generate team names when a team is first referred to unless the user has specified a name when requesting team creation.&lt;br /&gt;
*Handle team requirements with better abstraction:&lt;br /&gt;
*Try to eliminate direct logic in the controller that checks for specific assignment requirements such as topic handling.&lt;br /&gt;
*Rename student_team_requirements_met? to something more descriptive and break it into smaller methods checking individual conditions.&lt;br /&gt;
*Aim to decouple topics from this controller entirely, ensuring better abstraction, that can involve changes to other classes or introducing service objects to handle specific requirements.&lt;br /&gt;
* Improve feedback to users:&lt;br /&gt;
Ensure that the user receives clear and actionable feedback after operations like team creation, removal of users, and other key actions.&lt;br /&gt;
* Add comprehensive comments throughout the controller, clearly explaining the purpose and functionality of custom methods.&lt;br /&gt;
&lt;br /&gt;
===Testing Plan===&lt;br /&gt;
&lt;br /&gt;
We plan to perform comprehensive testing of the student_teams_controller.rb and related classes using RSPEC and leverage FactoryBot to construct the required test fixtures for testing extensive scenarios. Our approach involves reimplementing the existing test cases provided to the older code base and make sure that it is enhanced by covering more test scenarios to minimize code smells. We aim to verify the reimplemented functionality, validate the restructured code in the student_teams_controller.rb and reduce any design or code smell.&lt;br /&gt;
&lt;br /&gt;
===Mentor===&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Team Members===&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024&amp;diff=159043</id>
		<title>CSC/ECE 517 Fall 2024</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024&amp;diff=159043"/>
		<updated>2024-11-12T05:55:17Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: adding E.2476&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[CSC/ECE 517 Fall 2024 - E2450. Refactor assignments_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2451. Reimplement feedback_response_map.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2452. Refactor review_mapping_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2453. Refactor review_mapping_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2454. Refactor student_task.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2455. Refactor sign_up_sheet_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2456. Refactor teams_user.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2456. Refactor teams_user.rb (Phase 2 - Design Document)]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2458. User management and users table]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2459. View for results of bidding]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2460 Mentor-Meeting Management]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2461. UI for Courses]]&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2462._UI_for_Questionnaires CSC/ECE 517 Fall 2024 - E2462. UI for Questionnaire.rb]&lt;br /&gt;
* [https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2463_Implement_Front_End_for_Student_Task_List CSC/ECE 517 Fall 2024 - E2463. UI for Student Task List]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2464 UI for Project Topics (was: Sign_up_Topics)]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2465. UI for Institutions and Notification]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2466. UI for Impersonate User]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2467. UI for View Submissions]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2468. Reimplement due_date]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2469. Reimplement grades/view_team]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2470. Reimplement grades_controller]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2471. Reimplement logger]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2472. Reimplement responses_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2474. Reimplement student_quizzes_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2475. Reimplement student_task view]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2476. Reimplement student_teams_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2478. Reimplement the Question hierarchy as Item hierarchy]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2479. Reimplement teams_users_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2480. Implement testing for new Bookmarks Controller]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2481 Reimplement response_map.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2482. Reimplement heatgrid for reviews]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2483. Reimplement Notification Controller and Model]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2484. Reimplement participants_controller.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2485. Allow reviewers to bid on what to review]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2487. Reimplement authorization_helper.rb]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2492. UI for View submissions/assign grades (except heatgrid)]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - E2493. UI for Assign Reviewers]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - G2401 Refactor Graphql API endpoint for contribution metrics]]&lt;br /&gt;
* [[CSC/ECE 517 Fall 2024 - G2402 Refactor Graphql API endpoint for repositories]]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158555</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158555"/>
		<updated>2024-10-30T03:59:23Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Login Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Login Details==&lt;br /&gt;
&lt;br /&gt;
* [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;br /&gt;
* username = instructor6&lt;br /&gt;
* password = password&lt;br /&gt;
&lt;br /&gt;
===Note===&lt;br /&gt;
Switch from instructor view to student view, you can find it at the top of website.&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====Descriptive test cases====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Accessing the Assignments Page'''&lt;br /&gt;
    - Objective: Verify that the assignments page is accessible and displays all available assignments.&lt;br /&gt;
    - Steps: Navigate to the **Assignments** tab and confirm that it loads without errors, displaying the list of assignments.&lt;br /&gt;
&lt;br /&gt;
* '''Selecting an Assignment'''&lt;br /&gt;
    - Objective: Confirm that selecting an assignment redirects the user to the detailed view.&lt;br /&gt;
    - Steps: From the **Assignments** page, click on any assignment and verify that you are redirected to the respective **StudentTask** page for that assignment.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Assignment Details'''&lt;br /&gt;
    - Objective: Ensure that the **StudentTask** page displays assignment details, such as course, topic, and current stage.&lt;br /&gt;
    - Steps: On the **StudentTask** page, verify the presence of fields like course, topic, and current stage, ensuring accuracy in the information displayed.&lt;br /&gt;
&lt;br /&gt;
* '''Navigating &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; Links'''&lt;br /&gt;
    - Objective: Test the links to &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; sections to confirm they display relevant information.&lt;br /&gt;
    - Steps: Click the **Your Work** link to confirm it shows the student's submissions; then click the **Others' Work** link to verify it shows other students’ work or available feedback options, as applicable.&lt;br /&gt;
&lt;br /&gt;
* '''Checking Review Grade Information'''&lt;br /&gt;
    - Objective: Verify that the review grade, if available, is displayed along with any awarded badges.&lt;br /&gt;
    - Steps: Confirm the **Review Grade** section displays either a numeric grade or &amp;quot;N/A&amp;quot; if no grade is available, and ensure any badges appear with accurate images and tooltips.&lt;br /&gt;
&lt;br /&gt;
* '''Assignment Timelines and Deadline Tasks'''&lt;br /&gt;
    - Objective: Verify that each assignment timeline and associated deadlines are listed on the StudentTask page.&lt;br /&gt;
    - Steps: Navigate to the **Assignment Timelines** section and confirm that each task is listed in order with relevant due dates.&lt;br /&gt;
&lt;br /&gt;
* '''Checking and Sending Reviewer Emails'''&lt;br /&gt;
    - Objective: Test the &amp;quot;Send Email to Reviewers&amp;quot; feature to ensure it functions as expected.&lt;br /&gt;
    - Steps: On the **StudentTask** page, select the **Send Email to Reviewers** option and confirm the email interface opens, allowing the student to message reviewers.&lt;br /&gt;
&lt;br /&gt;
* '''Revisions and Unstarted Tasks'''&lt;br /&gt;
    - Objective: Verify that any revisions and unstarted tasks for the assignment are displayed accurately.&lt;br /&gt;
    - Steps: Check for sections labeled **Revisions** and **Tasks Not Yet Started**, and confirm that each section lists the student’s pending tasks correctly.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Teammates and Course Association'''&lt;br /&gt;
    - Objective: Confirm that teammates and course association are accurately displayed for assignments.&lt;br /&gt;
    - Steps: In the **Students Who Are Teamed with You** section, ensure teammates’ names and roles are displayed. Check that the assignment shows an association with a course name if applicable, or confirms if it is not associated with any course.&lt;br /&gt;
&lt;br /&gt;
====New RSpec Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158552</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158552"/>
		<updated>2024-10-30T03:58:12Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Login Details==&lt;br /&gt;
&lt;br /&gt;
* [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;br /&gt;
* username = instructor6&lt;br /&gt;
* password = password&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====Descriptive test cases====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Accessing the Assignments Page'''&lt;br /&gt;
    - Objective: Verify that the assignments page is accessible and displays all available assignments.&lt;br /&gt;
    - Steps: Navigate to the **Assignments** tab and confirm that it loads without errors, displaying the list of assignments.&lt;br /&gt;
&lt;br /&gt;
* '''Selecting an Assignment'''&lt;br /&gt;
    - Objective: Confirm that selecting an assignment redirects the user to the detailed view.&lt;br /&gt;
    - Steps: From the **Assignments** page, click on any assignment and verify that you are redirected to the respective **StudentTask** page for that assignment.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Assignment Details'''&lt;br /&gt;
    - Objective: Ensure that the **StudentTask** page displays assignment details, such as course, topic, and current stage.&lt;br /&gt;
    - Steps: On the **StudentTask** page, verify the presence of fields like course, topic, and current stage, ensuring accuracy in the information displayed.&lt;br /&gt;
&lt;br /&gt;
* '''Navigating &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; Links'''&lt;br /&gt;
    - Objective: Test the links to &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; sections to confirm they display relevant information.&lt;br /&gt;
    - Steps: Click the **Your Work** link to confirm it shows the student's submissions; then click the **Others' Work** link to verify it shows other students’ work or available feedback options, as applicable.&lt;br /&gt;
&lt;br /&gt;
* '''Checking Review Grade Information'''&lt;br /&gt;
    - Objective: Verify that the review grade, if available, is displayed along with any awarded badges.&lt;br /&gt;
    - Steps: Confirm the **Review Grade** section displays either a numeric grade or &amp;quot;N/A&amp;quot; if no grade is available, and ensure any badges appear with accurate images and tooltips.&lt;br /&gt;
&lt;br /&gt;
* '''Assignment Timelines and Deadline Tasks'''&lt;br /&gt;
    - Objective: Verify that each assignment timeline and associated deadlines are listed on the StudentTask page.&lt;br /&gt;
    - Steps: Navigate to the **Assignment Timelines** section and confirm that each task is listed in order with relevant due dates.&lt;br /&gt;
&lt;br /&gt;
* '''Checking and Sending Reviewer Emails'''&lt;br /&gt;
    - Objective: Test the &amp;quot;Send Email to Reviewers&amp;quot; feature to ensure it functions as expected.&lt;br /&gt;
    - Steps: On the **StudentTask** page, select the **Send Email to Reviewers** option and confirm the email interface opens, allowing the student to message reviewers.&lt;br /&gt;
&lt;br /&gt;
* '''Revisions and Unstarted Tasks'''&lt;br /&gt;
    - Objective: Verify that any revisions and unstarted tasks for the assignment are displayed accurately.&lt;br /&gt;
    - Steps: Check for sections labeled **Revisions** and **Tasks Not Yet Started**, and confirm that each section lists the student’s pending tasks correctly.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Teammates and Course Association'''&lt;br /&gt;
    - Objective: Confirm that teammates and course association are accurately displayed for assignments.&lt;br /&gt;
    - Steps: In the **Students Who Are Teamed with You** section, ensure teammates’ names and roles are displayed. Check that the assignment shows an association with a course name if applicable, or confirms if it is not associated with any course.&lt;br /&gt;
&lt;br /&gt;
====New RSpec Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158551</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158551"/>
		<updated>2024-10-30T03:57:55Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Login Details */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Login Details==&lt;br /&gt;
&lt;br /&gt;
* [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;br /&gt;
* username = instructor6&lt;br /&gt;
* password = password&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====Descriptive test cases====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Accessing the Assignments Page'''&lt;br /&gt;
    - Objective: Verify that the assignments page is accessible and displays all available assignments.&lt;br /&gt;
    - Steps: Navigate to the **Assignments** tab and confirm that it loads without errors, displaying the list of assignments.&lt;br /&gt;
&lt;br /&gt;
* '''Selecting an Assignment'''&lt;br /&gt;
    - Objective: Confirm that selecting an assignment redirects the user to the detailed view.&lt;br /&gt;
    - Steps: From the **Assignments** page, click on any assignment and verify that you are redirected to the respective **StudentTask** page for that assignment.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Assignment Details'''&lt;br /&gt;
    - Objective: Ensure that the **StudentTask** page displays assignment details, such as course, topic, and current stage.&lt;br /&gt;
    - Steps: On the **StudentTask** page, verify the presence of fields like course, topic, and current stage, ensuring accuracy in the information displayed.&lt;br /&gt;
&lt;br /&gt;
* '''Navigating &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; Links'''&lt;br /&gt;
    - Objective: Test the links to &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; sections to confirm they display relevant information.&lt;br /&gt;
    - Steps: Click the **Your Work** link to confirm it shows the student's submissions; then click the **Others' Work** link to verify it shows other students’ work or available feedback options, as applicable.&lt;br /&gt;
&lt;br /&gt;
* '''Checking Review Grade Information'''&lt;br /&gt;
    - Objective: Verify that the review grade, if available, is displayed along with any awarded badges.&lt;br /&gt;
    - Steps: Confirm the **Review Grade** section displays either a numeric grade or &amp;quot;N/A&amp;quot; if no grade is available, and ensure any badges appear with accurate images and tooltips.&lt;br /&gt;
&lt;br /&gt;
* '''Assignment Timelines and Deadline Tasks'''&lt;br /&gt;
    - Objective: Verify that each assignment timeline and associated deadlines are listed on the StudentTask page.&lt;br /&gt;
    - Steps: Navigate to the **Assignment Timelines** section and confirm that each task is listed in order with relevant due dates.&lt;br /&gt;
&lt;br /&gt;
* '''Checking and Sending Reviewer Emails'''&lt;br /&gt;
    - Objective: Test the &amp;quot;Send Email to Reviewers&amp;quot; feature to ensure it functions as expected.&lt;br /&gt;
    - Steps: On the **StudentTask** page, select the **Send Email to Reviewers** option and confirm the email interface opens, allowing the student to message reviewers.&lt;br /&gt;
&lt;br /&gt;
* '''Revisions and Unstarted Tasks'''&lt;br /&gt;
    - Objective: Verify that any revisions and unstarted tasks for the assignment are displayed accurately.&lt;br /&gt;
    - Steps: Check for sections labeled **Revisions** and **Tasks Not Yet Started**, and confirm that each section lists the student’s pending tasks correctly.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Teammates and Course Association'''&lt;br /&gt;
    - Objective: Confirm that teammates and course association are accurately displayed for assignments.&lt;br /&gt;
    - Steps: In the **Students Who Are Teamed with You** section, ensure teammates’ names and roles are displayed. Check that the assignment shows an association with a course name if applicable, or confirms if it is not associated with any course.&lt;br /&gt;
&lt;br /&gt;
====New RSpec Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158549</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158549"/>
		<updated>2024-10-30T03:57:11Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Refactoring */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Login Details==&lt;br /&gt;
&lt;br /&gt;
* username = instructor6&lt;br /&gt;
* password = password&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====Descriptive test cases====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Accessing the Assignments Page'''&lt;br /&gt;
    - Objective: Verify that the assignments page is accessible and displays all available assignments.&lt;br /&gt;
    - Steps: Navigate to the **Assignments** tab and confirm that it loads without errors, displaying the list of assignments.&lt;br /&gt;
&lt;br /&gt;
* '''Selecting an Assignment'''&lt;br /&gt;
    - Objective: Confirm that selecting an assignment redirects the user to the detailed view.&lt;br /&gt;
    - Steps: From the **Assignments** page, click on any assignment and verify that you are redirected to the respective **StudentTask** page for that assignment.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Assignment Details'''&lt;br /&gt;
    - Objective: Ensure that the **StudentTask** page displays assignment details, such as course, topic, and current stage.&lt;br /&gt;
    - Steps: On the **StudentTask** page, verify the presence of fields like course, topic, and current stage, ensuring accuracy in the information displayed.&lt;br /&gt;
&lt;br /&gt;
* '''Navigating &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; Links'''&lt;br /&gt;
    - Objective: Test the links to &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; sections to confirm they display relevant information.&lt;br /&gt;
    - Steps: Click the **Your Work** link to confirm it shows the student's submissions; then click the **Others' Work** link to verify it shows other students’ work or available feedback options, as applicable.&lt;br /&gt;
&lt;br /&gt;
* '''Checking Review Grade Information'''&lt;br /&gt;
    - Objective: Verify that the review grade, if available, is displayed along with any awarded badges.&lt;br /&gt;
    - Steps: Confirm the **Review Grade** section displays either a numeric grade or &amp;quot;N/A&amp;quot; if no grade is available, and ensure any badges appear with accurate images and tooltips.&lt;br /&gt;
&lt;br /&gt;
* '''Assignment Timelines and Deadline Tasks'''&lt;br /&gt;
    - Objective: Verify that each assignment timeline and associated deadlines are listed on the StudentTask page.&lt;br /&gt;
    - Steps: Navigate to the **Assignment Timelines** section and confirm that each task is listed in order with relevant due dates.&lt;br /&gt;
&lt;br /&gt;
* '''Checking and Sending Reviewer Emails'''&lt;br /&gt;
    - Objective: Test the &amp;quot;Send Email to Reviewers&amp;quot; feature to ensure it functions as expected.&lt;br /&gt;
    - Steps: On the **StudentTask** page, select the **Send Email to Reviewers** option and confirm the email interface opens, allowing the student to message reviewers.&lt;br /&gt;
&lt;br /&gt;
* '''Revisions and Unstarted Tasks'''&lt;br /&gt;
    - Objective: Verify that any revisions and unstarted tasks for the assignment are displayed accurately.&lt;br /&gt;
    - Steps: Check for sections labeled **Revisions** and **Tasks Not Yet Started**, and confirm that each section lists the student’s pending tasks correctly.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Teammates and Course Association'''&lt;br /&gt;
    - Objective: Confirm that teammates and course association are accurately displayed for assignments.&lt;br /&gt;
    - Steps: In the **Students Who Are Teamed with You** section, ensure teammates’ names and roles are displayed. Check that the assignment shows an association with a course name if applicable, or confirms if it is not associated with any course.&lt;br /&gt;
&lt;br /&gt;
====New RSpec Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158544</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158544"/>
		<updated>2024-10-30T03:55:35Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Descriptive test cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====Descriptive test cases====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* '''Accessing the Assignments Page'''&lt;br /&gt;
    - Objective: Verify that the assignments page is accessible and displays all available assignments.&lt;br /&gt;
    - Steps: Navigate to the **Assignments** tab and confirm that it loads without errors, displaying the list of assignments.&lt;br /&gt;
&lt;br /&gt;
* '''Selecting an Assignment'''&lt;br /&gt;
    - Objective: Confirm that selecting an assignment redirects the user to the detailed view.&lt;br /&gt;
    - Steps: From the **Assignments** page, click on any assignment and verify that you are redirected to the respective **StudentTask** page for that assignment.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Assignment Details'''&lt;br /&gt;
    - Objective: Ensure that the **StudentTask** page displays assignment details, such as course, topic, and current stage.&lt;br /&gt;
    - Steps: On the **StudentTask** page, verify the presence of fields like course, topic, and current stage, ensuring accuracy in the information displayed.&lt;br /&gt;
&lt;br /&gt;
* '''Navigating &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; Links'''&lt;br /&gt;
    - Objective: Test the links to &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; sections to confirm they display relevant information.&lt;br /&gt;
    - Steps: Click the **Your Work** link to confirm it shows the student's submissions; then click the **Others' Work** link to verify it shows other students’ work or available feedback options, as applicable.&lt;br /&gt;
&lt;br /&gt;
* '''Checking Review Grade Information'''&lt;br /&gt;
    - Objective: Verify that the review grade, if available, is displayed along with any awarded badges.&lt;br /&gt;
    - Steps: Confirm the **Review Grade** section displays either a numeric grade or &amp;quot;N/A&amp;quot; if no grade is available, and ensure any badges appear with accurate images and tooltips.&lt;br /&gt;
&lt;br /&gt;
* '''Assignment Timelines and Deadline Tasks'''&lt;br /&gt;
    - Objective: Verify that each assignment timeline and associated deadlines are listed on the StudentTask page.&lt;br /&gt;
    - Steps: Navigate to the **Assignment Timelines** section and confirm that each task is listed in order with relevant due dates.&lt;br /&gt;
&lt;br /&gt;
* '''Checking and Sending Reviewer Emails'''&lt;br /&gt;
    - Objective: Test the &amp;quot;Send Email to Reviewers&amp;quot; feature to ensure it functions as expected.&lt;br /&gt;
    - Steps: On the **StudentTask** page, select the **Send Email to Reviewers** option and confirm the email interface opens, allowing the student to message reviewers.&lt;br /&gt;
&lt;br /&gt;
* '''Revisions and Unstarted Tasks'''&lt;br /&gt;
    - Objective: Verify that any revisions and unstarted tasks for the assignment are displayed accurately.&lt;br /&gt;
    - Steps: Check for sections labeled **Revisions** and **Tasks Not Yet Started**, and confirm that each section lists the student’s pending tasks correctly.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Teammates and Course Association'''&lt;br /&gt;
    - Objective: Confirm that teammates and course association are accurately displayed for assignments.&lt;br /&gt;
    - Steps: In the **Students Who Are Teamed with You** section, ensure teammates’ names and roles are displayed. Check that the assignment shows an association with a course name if applicable, or confirms if it is not associated with any course.&lt;br /&gt;
&lt;br /&gt;
====New RSpec Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158542</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158542"/>
		<updated>2024-10-30T03:55:27Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Descriptive test cases */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====Descriptive test cases====&lt;br /&gt;
&lt;br /&gt;
* '''Accessing the Assignments Page'''&lt;br /&gt;
    - Objective: Verify that the assignments page is accessible and displays all available assignments.&lt;br /&gt;
    - Steps: Navigate to the **Assignments** tab and confirm that it loads without errors, displaying the list of assignments.&lt;br /&gt;
&lt;br /&gt;
* '''Selecting an Assignment'''&lt;br /&gt;
    - Objective: Confirm that selecting an assignment redirects the user to the detailed view.&lt;br /&gt;
    - Steps: From the **Assignments** page, click on any assignment and verify that you are redirected to the respective **StudentTask** page for that assignment.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Assignment Details'''&lt;br /&gt;
    - Objective: Ensure that the **StudentTask** page displays assignment details, such as course, topic, and current stage.&lt;br /&gt;
    - Steps: On the **StudentTask** page, verify the presence of fields like course, topic, and current stage, ensuring accuracy in the information displayed.&lt;br /&gt;
&lt;br /&gt;
* '''Navigating &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; Links'''&lt;br /&gt;
    - Objective: Test the links to &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; sections to confirm they display relevant information.&lt;br /&gt;
    - Steps: Click the **Your Work** link to confirm it shows the student's submissions; then click the **Others' Work** link to verify it shows other students’ work or available feedback options, as applicable.&lt;br /&gt;
&lt;br /&gt;
* '''Checking Review Grade Information'''&lt;br /&gt;
    - Objective: Verify that the review grade, if available, is displayed along with any awarded badges.&lt;br /&gt;
    - Steps: Confirm the **Review Grade** section displays either a numeric grade or &amp;quot;N/A&amp;quot; if no grade is available, and ensure any badges appear with accurate images and tooltips.&lt;br /&gt;
&lt;br /&gt;
* '''Assignment Timelines and Deadline Tasks'''&lt;br /&gt;
    - Objective: Verify that each assignment timeline and associated deadlines are listed on the StudentTask page.&lt;br /&gt;
    - Steps: Navigate to the **Assignment Timelines** section and confirm that each task is listed in order with relevant due dates.&lt;br /&gt;
&lt;br /&gt;
* '''Checking and Sending Reviewer Emails'''&lt;br /&gt;
    - Objective: Test the &amp;quot;Send Email to Reviewers&amp;quot; feature to ensure it functions as expected.&lt;br /&gt;
    - Steps: On the **StudentTask** page, select the **Send Email to Reviewers** option and confirm the email interface opens, allowing the student to message reviewers.&lt;br /&gt;
&lt;br /&gt;
* '''Revisions and Unstarted Tasks'''&lt;br /&gt;
    - Objective: Verify that any revisions and unstarted tasks for the assignment are displayed accurately.&lt;br /&gt;
    - Steps: Check for sections labeled **Revisions** and **Tasks Not Yet Started**, and confirm that each section lists the student’s pending tasks correctly.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Teammates and Course Association'''&lt;br /&gt;
    - Objective: Confirm that teammates and course association are accurately displayed for assignments.&lt;br /&gt;
    - Steps: In the **Students Who Are Teamed with You** section, ensure teammates’ names and roles are displayed. Check that the assignment shows an association with a course name if applicable, or confirms if it is not associated with any course.&lt;br /&gt;
&lt;br /&gt;
====New RSpec Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158538</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158538"/>
		<updated>2024-10-30T03:55:13Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====Descriptive test cases====&lt;br /&gt;
&lt;br /&gt;
'''Test Cases:'''&lt;br /&gt;
&lt;br /&gt;
* '''Accessing the Assignments Page'''&lt;br /&gt;
    - Objective: Verify that the assignments page is accessible and displays all available assignments.&lt;br /&gt;
    - Steps: Navigate to the **Assignments** tab and confirm that it loads without errors, displaying the list of assignments.&lt;br /&gt;
&lt;br /&gt;
* '''Selecting an Assignment'''&lt;br /&gt;
    - Objective: Confirm that selecting an assignment redirects the user to the detailed view.&lt;br /&gt;
    - Steps: From the **Assignments** page, click on any assignment and verify that you are redirected to the respective **StudentTask** page for that assignment.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Assignment Details'''&lt;br /&gt;
    - Objective: Ensure that the **StudentTask** page displays assignment details, such as course, topic, and current stage.&lt;br /&gt;
    - Steps: On the **StudentTask** page, verify the presence of fields like course, topic, and current stage, ensuring accuracy in the information displayed.&lt;br /&gt;
&lt;br /&gt;
* '''Navigating &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; Links'''&lt;br /&gt;
    - Objective: Test the links to &amp;quot;Your Work&amp;quot; and &amp;quot;Others' Work&amp;quot; sections to confirm they display relevant information.&lt;br /&gt;
    - Steps: Click the **Your Work** link to confirm it shows the student's submissions; then click the **Others' Work** link to verify it shows other students’ work or available feedback options, as applicable.&lt;br /&gt;
&lt;br /&gt;
* '''Checking Review Grade Information'''&lt;br /&gt;
    - Objective: Verify that the review grade, if available, is displayed along with any awarded badges.&lt;br /&gt;
    - Steps: Confirm the **Review Grade** section displays either a numeric grade or &amp;quot;N/A&amp;quot; if no grade is available, and ensure any badges appear with accurate images and tooltips.&lt;br /&gt;
&lt;br /&gt;
* '''Assignment Timelines and Deadline Tasks'''&lt;br /&gt;
    - Objective: Verify that each assignment timeline and associated deadlines are listed on the StudentTask page.&lt;br /&gt;
    - Steps: Navigate to the **Assignment Timelines** section and confirm that each task is listed in order with relevant due dates.&lt;br /&gt;
&lt;br /&gt;
* '''Checking and Sending Reviewer Emails'''&lt;br /&gt;
    - Objective: Test the &amp;quot;Send Email to Reviewers&amp;quot; feature to ensure it functions as expected.&lt;br /&gt;
    - Steps: On the **StudentTask** page, select the **Send Email to Reviewers** option and confirm the email interface opens, allowing the student to message reviewers.&lt;br /&gt;
&lt;br /&gt;
* '''Revisions and Unstarted Tasks'''&lt;br /&gt;
    - Objective: Verify that any revisions and unstarted tasks for the assignment are displayed accurately.&lt;br /&gt;
    - Steps: Check for sections labeled **Revisions** and **Tasks Not Yet Started**, and confirm that each section lists the student’s pending tasks correctly.&lt;br /&gt;
&lt;br /&gt;
* '''Viewing Teammates and Course Association'''&lt;br /&gt;
    - Objective: Confirm that teammates and course association are accurately displayed for assignments.&lt;br /&gt;
    - Steps: In the **Students Who Are Teamed with You** section, ensure teammates’ names and roles are displayed. Check that the assignment shows an association with a course name if applicable, or confirms if it is not associated with any course.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====New RSpec Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158493</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158493"/>
		<updated>2024-10-30T03:34:57Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====New Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158491</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158491"/>
		<updated>2024-10-30T03:33:51Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* self.peer_review_data(participant_id, timeline_list) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
Iterates through each peer review for a participant, yielding each review to a provided block.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====New Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Next Steps==&lt;br /&gt;
We are yet to discuss the scope of this project and whether it can be extended to other functionalities in Expertiza.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158487</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158487"/>
		<updated>2024-10-30T03:32:33Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Refactoring */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
====self.from_participant(participant)====&lt;br /&gt;
Creates a StudentTask instance for a given participant, populating it with relevant assignment and stage data.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.from_participantid(id)====&lt;br /&gt;
It searches and fetches an active participant by its id.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.from_user(user)====&lt;br /&gt;
Retrieves tasks associated with a user by iterating over the user's assignment participants and sorting them by their stage deadlines.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_author_feedback_data(participant_id, timeline_list)====&lt;br /&gt;
Generates a timeline of author feedback for a participant by mapping each feedback response through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_due_date_data(assignment, timeline_list)====&lt;br /&gt;
Generates a timeline of due dates for an assignment by mapping each due date through a parsing function.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.peer_review_data(participant_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.get_submission_data(participant_id, team_id, timeline_list)====&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
====self.get_timeline_data(assignment, participant, _team)====&lt;br /&gt;
Generates a timeline of events related to the assignment for the participant, including due dates, peer reviews, and author feedback, sorted by update time.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
====self.teamed_student(user, ip_address=nil)====&lt;br /&gt;
Groups teammates by course for a user and returns a hash where keys are course IDs and values are lists of teammate names.&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====New Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Next Steps==&lt;br /&gt;
We are yet to discuss the scope of this project and whether it can be extended to other functionalities in Expertiza.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158453</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158453"/>
		<updated>2024-10-30T03:23:17Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Functionality of StudentTask Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
self.from_participant(participant)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.from_participantid(id)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
self.from_user(user)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.get_author_feedback_data(participant_id, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.get_due_date_data(assignment, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.peer_review_data(participant_id, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.get_submission_data(participant_id, team_id, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
self.get_timeline_data(assignment, participant, _team)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.teamed_student(user, ip_address=nil)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====New Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Next Steps==&lt;br /&gt;
We are yet to discuss the scope of this project and whether it can be extended to other functionalities in Expertiza.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158447</id>
		<title>CSC/ECE 517 Fall 2024 - E2454. Refactor student task.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2024_-_E2454._Refactor_student_task.rb&amp;diff=158447"/>
		<updated>2024-10-30T03:21:15Z</updated>

		<summary type="html">&lt;p&gt;Akoul2: /* Functionality of StudentTask Model */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Expertiza==&lt;br /&gt;
&lt;br /&gt;
Expertiza is a web application through which students can submit and peer-review learning objects (articles, code, web sites, etc).&lt;br /&gt;
The National Science Foundation supports the Expertiza project.&lt;br /&gt;
It is used in select courses at NC State and by professors at several other colleges and universities.&lt;br /&gt;
&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a [http://rubyonrails.org/ Ruby on Rails] based open source project.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
&lt;br /&gt;
====Background====&lt;br /&gt;
This project focuses on refactoring the StudentTask class to improve the organization, functionality, and separation of concerns. Currently, the class contains a mix of utility and class methods, many of which are static and should be moved into helper modules or relevant model classes, or broken down into separate, more maintainable methods. The goal is to make the class more efficient and follow best practices in object-oriented programming.&lt;br /&gt;
&lt;br /&gt;
The StudentTask model is a significant part of the Expertiza website which maintains and handles student data who are participants under an assignment. Each assignment has a team, individual user participant and submission deadlines. The motive here is to refactor static methods called in the student_task.rb file and move them to helper classes for better object-oriented code design.&lt;br /&gt;
&lt;br /&gt;
==About StudentTask Model==&lt;br /&gt;
The StudentTask model handles the tracking and organizes of student assignments, encapsulating key information about a student’s current progress, deadlines, and associated tasks. It provides different functional methods for task creation, checking completion status, and timeline generation, ensuring a streamlined and detailed view of a student's assignment timelines. The model interacts closely with assignment participants and topics to display their task completion stages, reviews, and deadlines.&lt;br /&gt;
&lt;br /&gt;
===Functionality of StudentTask Model===&lt;br /&gt;
The StudentTask model manages student assignments with the help of functional methods to initialize tasks, track deadlines, and task assessment. It includes class method from_participant, which creates a task based on a participant’s data, and from_user, that generates a sorted list of tasks by deadline for a particular user. Task status is determined through methods such as complete?, incomplete?, and started?. Additionally The revision? method checks for ongoing updates based on current stage and submissions. The model also incorporates methods (such as get_due_date_data, get_submission_data, etc.) that compile task events in chronological order, enabling a clear overview of assignment deadlines, submissions, and peer reviews. Through encapsulation, delegation, and adherence to SRP, StudentTask ensures efficient and modular task tracking aligned with the required educational processes.&lt;br /&gt;
&lt;br /&gt;
==Functionality of StudentTaskHelper Module==&lt;br /&gt;
The StudentTaskHelper module facilitates efficient task management by handling operations such as timeline generation, teammate grouping, and task initialization for participants. It includes generate_timeline, which combines due date, peer review, and author feedback timelines, as well as create_student_task_for_participant to initialize tasks based on participant data. The module introduces iterator patterns through methods such as for_each_due_date_of_assignment, for_each_peer_review, and for_each_author_feedback, which yield data to enhance flexibility and modularity within the codebase.&lt;br /&gt;
&lt;br /&gt;
Helper methods like group_teammates_by_course_for_user efficiently organize teammates by course, while methods like parse_due_date_to_timeline and parse_response_to_timeline encapsulate logic for structuring timeline events. Using private helper methods such as fetch_response_from, and utility functions like calibration_assignment? and valid_assignment_team?, StudentTaskHelper optimizes data handling, improves readability, and adheres to object-oriented design principles by reducing the need for static methods in the StudentTask model.&lt;br /&gt;
&lt;br /&gt;
====Refactor====&lt;br /&gt;
&lt;br /&gt;
The StudentTask model do not strictly follow the SRP and DRY principles and needed a lot of refactoring to make them more manageable in following Object-Oriented design and development.&lt;br /&gt;
&lt;br /&gt;
Files modified:&lt;br /&gt;
* student_task.rb&lt;br /&gt;
* student_task_controller.rb&lt;br /&gt;
* student_task_helper.rb&lt;br /&gt;
* student_task_spec.rb&lt;br /&gt;
* assessment360_controller.rb&lt;br /&gt;
* assessment360_controller_spec.rb&lt;br /&gt;
&lt;br /&gt;
New files added:&lt;br /&gt;
* student_task_helper_spec.rb&lt;br /&gt;
&lt;br /&gt;
==Refactoring==&lt;br /&gt;
&lt;br /&gt;
self.from_participant(participant)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after1.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul from participant after2.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.from_participantid(id)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from participant id before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method is depreciated during the refactoring process. It no longer served its purpose and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
self.from_user(user)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 from user after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.get_author_feedback_data(participant_id, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get author feedback data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.get_due_date_data(assignment, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get due date after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.peer_review_data(participant_id, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 peer review data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get peer review data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.get_submission_data(participant_id, team_id, timeline_list)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get submission data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
 This method, similar to from_participantid(), didn't showcase its usefulness during the refactoring process and was removed from the codebase.&lt;br /&gt;
&lt;br /&gt;
self.get_timeline_data(assignment, participant, _team)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 get timeline data after.jpg]]&lt;br /&gt;
&lt;br /&gt;
self.teamed_student(user, ip_address=nil)&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student before.jpg]]&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 teamed student after.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additional methods added:&lt;br /&gt;
&lt;br /&gt;
[[File:Akoul2 additional methods.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Test Cases for StudentTask Model, Controller and helper classes==&lt;br /&gt;
&lt;br /&gt;
====New Test Cases====&lt;br /&gt;
&lt;br /&gt;
1. To check each due date of assignment:&lt;br /&gt;
&lt;br /&gt;
   describe '#for_each_due_date_of_assignment' do&lt;br /&gt;
    let(:due_date_modifier) do&lt;br /&gt;
      lambda { |dd|&lt;br /&gt;
        { label: (dd.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
          updated_at: dd.due_at.strftime('%a, %d %b %Y %H:%M') }&lt;br /&gt;
      }&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having empty due dates' do&lt;br /&gt;
      it 'return empty time_list array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when called with assignment having due date' do&lt;br /&gt;
      context 'and due_at value nil' do&lt;br /&gt;
        it 'return empty time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          due_date.due_at = nil&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) { |due_date| timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date) }&lt;br /&gt;
          expect(timeline_list).to eq([])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      context 'and due_at value not nil' do&lt;br /&gt;
        it 'return time_list array' do&lt;br /&gt;
          allow(due_date).to receive(:deadline_type).and_return(deadline_type)&lt;br /&gt;
          timeline_list = []&lt;br /&gt;
          assignment.due_dates = [due_date]&lt;br /&gt;
          student_task_helper.for_each_due_date_of_assignment(assignment) do |due_date|&lt;br /&gt;
            timeline_list &amp;lt;&amp;lt; due_date_modifier.call(due_date)&lt;br /&gt;
          end&lt;br /&gt;
          expect(timeline_list).to eq([{&lt;br /&gt;
                                        label: (due_date.deadline_type.name + ' Deadline').humanize,&lt;br /&gt;
                                        updated_at: due_date.due_at.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
                                      }])&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
2. To check for peer reviews&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_peer_review' do&lt;br /&gt;
    context 'when no review response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_peer_review(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, &amp;quot;Round #{response.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to review response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(ReviewResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:round).and_return(1)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.new(2019))&lt;br /&gt;
        timevalue = Time.new(2019).strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        for_each_peer_review(1) do |resp|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(resp, &amp;quot;Round #{resp.round} Peer Review&amp;quot;.humanize)&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Round 1 peer review', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
3. To check and validate author feedbacks&lt;br /&gt;
&lt;br /&gt;
  describe '#for_each_author_feedback' do&lt;br /&gt;
    context 'when no feedback response mapped' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(user2) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when mapped to feedback response map' do&lt;br /&gt;
      it 'returns timeline array' do&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        allow(FeedbackResponseMap).to receive_message_chain(:where, :find_each).with(reviewer_id: 1).with(no_args).and_yield(review_response_map)&lt;br /&gt;
        allow(review_response_map).to receive(:id).and_return(1)&lt;br /&gt;
        allow(Response).to receive_message_chain(:where, :last).with(map_id: 1).with(no_args).and_return(response)&lt;br /&gt;
        allow(response).to receive(:updated_at).and_return(Time.now)&lt;br /&gt;
        timevalue = Time.now.strftime('%a, %d %b %Y %H:%M')&lt;br /&gt;
        timeline_list = []&lt;br /&gt;
        for_each_author_feedback(1) do |response|&lt;br /&gt;
          timeline_list &amp;lt;&amp;lt; response_modifier.call(response, 'Author feedback')&lt;br /&gt;
        end&lt;br /&gt;
        expect(timeline_list).to eq([{ id: 1, label: 'Author feedback', updated_at: timevalue }])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
4. To create and validate generated timelines&lt;br /&gt;
&lt;br /&gt;
 describe '#generate_timeline' do&lt;br /&gt;
    context 'when no timeline data mapped' do&lt;br /&gt;
      it 'returns nil' do&lt;br /&gt;
        allow(participant).to receive(:get_reviewer).and_return(participant)&lt;br /&gt;
        expect(student_task_helper.generate_timeline(assignment, participant)).to eq([])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
5. Check if StudentTask obeject is created properly&lt;br /&gt;
&lt;br /&gt;
  describe '#create_student_task_for_participant' do&lt;br /&gt;
    it 'creates a StudentTask with the correct attributes' do&lt;br /&gt;
      student_task = student_task_helper.create_student_task_for_participant(participant3)&lt;br /&gt;
      expect(student_task).to be_an_instance_of(StudentTask)&lt;br /&gt;
      expect(student_task.participant).to eq(participant3)&lt;br /&gt;
      expect(student_task.assignment).to eq(assignment)&lt;br /&gt;
      expect(student_task.topic).to eq(topic)&lt;br /&gt;
      expect(student_task.current_stage).to eq('submission')&lt;br /&gt;
      expect(student_task.stage_deadline).to eq(Time.parse('2024-12-31 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
6. To check the retrieved tasks for users&lt;br /&gt;
&lt;br /&gt;
  describe '#retrieve_tasks_for_user' do&lt;br /&gt;
    before do&lt;br /&gt;
      allow(user).to receive_message_chain(:assignment_participants, :includes).and_return([participant4, participant5])&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'retrieves and sorts tasks by stage_deadline' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      expect(tasks.size).to eq(2)&lt;br /&gt;
      expect(tasks.first.stage_deadline).to eq(Time.parse('2024-11-01 12:00:00'))&lt;br /&gt;
      expect(tasks.last.stage_deadline).to eq(Time.parse('2024-12-01 12:00:00'))&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    it 'creates StudentTask objects for each participant' do&lt;br /&gt;
      tasks = student_task_helper.retrieve_tasks_for_user(user)&lt;br /&gt;
      tasks.each do |task|&lt;br /&gt;
        expect(task).to be_an_instance_of(StudentTask)&lt;br /&gt;
        expect(task.participant).to be_in([participant4, participant5])&lt;br /&gt;
        expect(task.assignment).to eq(assignment)&lt;br /&gt;
        expect(task.topic).to eq(topic)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
7. To check if deadlines are parsed properly&lt;br /&gt;
&lt;br /&gt;
  describe '#parse_stage_deadline' do&lt;br /&gt;
    context 'If a valid time value is given' do&lt;br /&gt;
      it 'parse the provided time correctly' do&lt;br /&gt;
        given_time = '2024-12-31 12:00:00'&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to eq(Time.parse(given_time))&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'If given time string is invalid' do&lt;br /&gt;
      it 'return current time plus 1 year' do&lt;br /&gt;
        given_time = 'invalid-time-string'&lt;br /&gt;
        overhead_time = Time.now + 1.year&lt;br /&gt;
        parsed_time = student_task_helper.parse_stage_deadline(given_time)&lt;br /&gt;
        expect(parsed_time).to be_within(1.second).of(overhead_time)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
8. To check various conditions of users tagged as teammates&lt;br /&gt;
&lt;br /&gt;
  describe '#group_teammates_by_course_for_user' do&lt;br /&gt;
    context 'when not in any team' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user3)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a course_team ' do&lt;br /&gt;
      it 'returns empty' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([course_team])&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq({})&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    context 'when assigned in a assignment_team ' do&lt;br /&gt;
      it 'returns the students they are teamed with' do&lt;br /&gt;
        allow(user).to receive(:teams).and_return([team])&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 1, parent_id: assignment.id).and_return(participant)&lt;br /&gt;
        allow(AssignmentParticipant).to receive(:find_by).with(user_id: 5, parent_id: assignment.id).and_return(participant2)&lt;br /&gt;
        allow(Assignment).to receive(:find_by).with(id: team.parent_id).and_return(assignment)&lt;br /&gt;
        expect(student_task_helper.group_teammates_by_course_for_user(user)).to eq(assignment.course_id =&amp;gt; [user2.fullname])&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
==Next Steps==&lt;br /&gt;
We are yet to discuss the scope of this project and whether it can be extended to other functionalities in Expertiza.&lt;br /&gt;
&lt;br /&gt;
==Team==&lt;br /&gt;
&lt;br /&gt;
====Mentor====&lt;br /&gt;
&lt;br /&gt;
* Ammana, Sahithi &amp;lt;sammana@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Members====&lt;br /&gt;
&lt;br /&gt;
* Eathamukkala, Akarsh Reddy   &amp;lt;aeatham@ncsu.edu&amp;gt;&lt;br /&gt;
* Koul, Anmol                  &amp;lt;akoul2@ncsu.edu&amp;gt;&lt;br /&gt;
* More, Harsh                  &amp;lt;hmore@ncsu.edu&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
&lt;br /&gt;
# [https://expertiza.ncsu.edu/ Expertiza]&lt;br /&gt;
# [https://docs.google.com/document/d/1fB9nHsop_yptjcj3CFn80BcZjXcSDbzcWwKvBDUTVrQ/edit?tab=t.0 OSS Projects on Expertiza]&lt;br /&gt;
# [https://github.com/expertiza/expertiza Github]&lt;br /&gt;
# [https://github.com/expertiza/expertiza/pull/2859 Pull Request]&lt;br /&gt;
# [http://152.7.177.54:8080/ Expertiza VCL Server]&lt;/div&gt;</summary>
		<author><name>Akoul2</name></author>
	</entry>
</feed>