CSC/ECE 517 Fall 2023 - E2386. Reimplement teams users backend: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(22 intermediate revisions by the same user not shown)
Line 1: Line 1:
===Description of Project===
==Description of Project==


The focal point of the project is the teams_user model, capturing information about team members, and affiliations with other models such as Users and Teams. This model undertakes various responsibilities, including the formation of teams with enrolled students and the display of team members. Oversight of team management falls under the purview of the teams_user_controller, which orchestrates CRUD operations on the teams_user model. Its duties span the creation, modification, and deletion of teams, along with the administration of team members through additions or removals.
The focal point of the project is the teams_users_controller.rb, teams_user.rb model capturing information about team members, and affiliations with other models such as Users and Teams. This model undertakes various responsibilities, including the formation of teams with enrolled students and the display of team members. Oversight of team management falls under the purview of the teams_user_controller, which orchestrates CRUD operations on the teams_user model. Its duties span the creation, modification, and deletion of teams, along with the administration of team members through additions or removals.


===Problem Statement===
==Problem Statement==


The project involves creating a backend system for seamless CRUD operations on a relational database, specifically focusing on interactions between teams and users. This requires defining "teams_users" model with suitable attributes and relationships, establishing controllers to manage CRUD actions, and setting up corresponding routes. Emphasis is placed on rigorous testing, covering model validations and associations, as well as controller actions to ensure accurate execution of CRUD operations. A key project aspect involves refining code to produce precise JSON responses. Adhering to RESTful conventions, the re-implementation includes appropriate HTTP response codes. RSpec tests are mandatory for both the teams_users model and TeamUsersController, covering all endpoints and incorporating HTTP response codes. These controller tests are designed to integrate seamlessly with RSwag for generating API documentation and testing REST APIs through the Swagger UI.
The main aim of the project is to create a backend for teams_users_controller. The team needs to write appropriate test cases for the models as well as refactor the code to make sure the correct JSON response is being returned. The project involves creating a backend system for seamless CRUD operations on a relational database, specifically focusing on interactions between teams and users. This requires defining "teams_users" model with suitable attributes and relationships, establishing controllers to manage CRUD actions, and setting up corresponding routes. Emphasis is placed on rigorous testing, covering model validations and associations, as well as controller actions to ensure accurate execution of CRUD operations. A key project aspect involves refining code to produce precise JSON responses. Adhering to RESTful conventions, the re-implementation includes appropriate HTTP response codes. RSpec tests are mandatory for both the teams_users model and TeamUsersController, covering all endpoints and incorporating HTTP response codes. These controller tests are designed to integrate seamlessly with RSwag for generating API documentation and testing REST APIs through the Swagger UI.


===Objectives===
==Objectives==


*Craft RESTful endpoints for creating, displaying, and deleting invitations, along with approving new invitations. Additionally, provide functionality for listing pending invitations, creating new invitations, and notifying students about newly formed team invitations.
*Craft RESTful endpoints for creating, displaying, updating and deleting teams users.  


*Develop and integrate methods within the teams_users_controller to facilitate invitation-related operations, including creating, accepting, declining, and canceling invitations. Ensure thorough checks of user and team statuses before initiating or accepting invitations.
*Develop and integrate methods within the teams_users_controller to facilitate CRUD operations
 
*Establish a user-invitation system that empowers invited users to accept, decline, or cancel invitations, triggering corresponding updates to the associated teams_user records. This should seamlessly manage the addition or removal of users from teams.
 
*Implement an email notification system within the user-invitation framework, sending email notifications to invited users upon the issuance of new invitations.


*Enforce the use of proper status codes and robust validation mechanisms for all RESTful endpoints.
*Enforce the use of proper status codes and robust validation mechanisms for all RESTful endpoints.
Line 21: Line 17:
*Construct models and controllers for the teams_user model, incorporating contemporary approaches to writing Ruby code. This involves leveraging language features and adhering to best practices for object-oriented design.
*Construct models and controllers for the teams_user model, incorporating contemporary approaches to writing Ruby code. This involves leveraging language features and adhering to best practices for object-oriented design.


*Compose comprehensive RSpec tests covering all APIs, models, and controllers to ensure the robustness and reliability of the entire system.
*Compose comprehensive RSpec tests covering both the models, and controllers to ensure the robustness and reliability of the entire system.
 
===Development Strategy===


Our development strategy adheres to the principles of Test-Driven Development (TDD) for the implementation of both the Invitation model and the Invitation Controller. The process begins with the creation of a failing test case, followed by the addition of code to address the identified issues and ensure the successful passage of the test.
==Development Strategy, Project Design and Implementation==


Furthermore, we align with the Rails philosophy of "Fat models," aiming to migrate substantial business logic from the controller to the model. This approach is intended to maintain a clean and organized controller codebase while promoting code reusability throughout the application.
Our development strategy adheres to the principles of Test-Driven Development (TDD) for the implementation of both the teams_user model and the TeamsUsersController. The process begins with the creation of a failing test case, followed by the addition of code to address the identified issues and ensure the successful passage of the test.


===Project Design and Implementation===
We have added the teams_user model and TeamsUserController and have outlined a set of RESTful endpoints along with their corresponding request types for implementation to facilitate CRUD operations on teams_users.


Considering the existing functionality of the teams_user model and controller, we have outlined a set of RESTful endpoints along with their corresponding request types for implementation. In the controller, we plan to adopt the Strategy Pattern, leveraging its ability to encapsulate controller actions and facilitate easy extensibility and usability. This pattern will enable a structured approach to defining and managing the various operations the controller can perform.
=== Functionality ===
 
==== Functionality ====
In this project, we aim to add functions for the following:
In this project, we aim to add functions for the following:


1. Retrieve and display team members.
1. Retrieve teams_users of a particular team from the database.


2. Add a new team member with checks for user existence and team limits.
2. Display all teams_users.


3. Delete a specific team member.
3. Add a new teams_user.  


4. Delete multiple selected team members based on item IDs.
4. Update an existing teams_user.


5. Autocomplete functionality for user names within a team.
4. Delete a specific teams_user.
 
6. Updating duties of a team member.


===Code Snippets===
===Code Snippets===


====Model====
====Model====
The `TeamsUser` model in the Expertiza code represents a user's association with a team within the context of a collaborative assignment or project. It utilizes ActiveRecord associations to establish relationships with the `User` and `Team` models, indicating that a user belongs to a team. The model includes methods for deleting a team user, retrieving team members, removing a user from a team, checking if a team is empty, and adding a member to an invited team based on certain conditions. Additionally, there's a method for determining the team ID associated with a user in a specific assignment.
The `TeamsUser` model in the Expertiza code represents a user's association with a team within the context of a collaborative assignment or project. It utilizes ActiveRecord associations to establish relationships with the `User` and `Team` models, indicating that a user belongs to a team. The model includes methods to return the name of the user based on ip_address. Then it includes a method that removes entry in the TeamUsers table for the given user and given team id. Another method returns the first entry in the TeamUsers table for a given team id and the last method determines whether a team is empty or not.
 


<pre>
<pre>
Line 57: Line 48:
   belongs_to :user
   belongs_to :user
   belongs_to :team
   belongs_to :team
  has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy
  has_paper_trail
  # attr_accessible :user_id, :team_id # unnecessary protected attributes


   def name(ip_address = nil)
   def name(ip_address = nil)
     name = user.name(ip_address)
     name = user.name(ip_address)
    # E2115 Mentor Management
    # Indicate that someone is a Mentor in the UI. The view code is
    # often hard to follow, and this is the best place we could find
    # for this to go.
    name += ' (Mentor)' if MentorManagement.user_a_mentor?(user)
    name
  end
  def delete
    TeamUserNode.find_by(node_object_id: id).destroy
    team = self.team
    destroy
    team.delete if team.teams_users.empty?
   end
   end


Line 98: Line 72:
   end
   end


  # Add member to the team they were invited to and accepted the invite for
  def self.add_member_to_invited_team(invitee_user_id, invited_user_id, assignment_id)
    can_add_member = false
    users_teams = TeamsUser.where(['user_id = ?', invitee_user_id])
    users_teams.each do |team|
      new_team = AssignmentTeam.where(['id = ? and parent_id = ?', team.team_id, assignment_id]).first
      unless new_team.nil?
        can_add_member = new_team.add_member(User.find(invited_user_id), assignment_id)
      end
    end
    can_add_member
  end
  # 2015-5-27 [zhewei]:
  # We just remove the topic_id field from the participants table.
  def self.team_id(assignment_id, user_id)
    # team_id variable represents the team_id for this user in this assignment
    team_id = nil
    teams_users = TeamsUser.where(user_id: user_id)
    teams_users.each do |teams_user|
      if teams_user.team_id == nil
        next
      end
      team = Team.find(teams_user.team_id)
      if team.parent_id == assignment_id
        team_id = teams_user.team_id
        break
      end
    end
    team_id
  end
end
end
</pre>
</pre>


====Controller====
====Controller====
The `TeamsUsersController` handles various actions related to team management within the application. It includes methods for authorization checks, auto-completion of user names, updating team member duties, listing team members, creating new team members, deleting individual team members, and bulk deletion of selected team members. The controller also interacts with models such as `Team`, `Assignment`, `User`, and `TeamsUser` to manage teams, assignments, and users. Notably, the `create` method involves adding new team members, performing checks on user participation in assignments or courses, and triggering additional actions such as mentor assignments. The code emphasizes error handling and provides flash messages to communicate issues or successful operations to users.
The `TeamsUsersController` handles various actions related to team management within the application. It includes methods that lists all teams_users, gets the teams_users of a particular team, renders a form to create a new teams_user for a specific team, creates a new teams_user, updates an existing teams_user, removes a teams_user and calls methods on the TeamsUser model.


<pre>
<pre>
class TeamsUsersController < ApplicationController
class Api::V1::TeamsUsersController < ApplicationController
   include AuthorizationHelper
   before_action :find_teams_user, only: [:update, :destroy]


  def action_allowed?
    # Allow duty updation for a team if current user is student, else require TA or above Privileges.
    if %w[update_duties].include? params[:action]
      current_user_has_student_privileges?
    else
      current_user_has_ta_privileges?
    end
  end


   def auto_complete_for_user_name
   rescue_from ActiveRecord::RecordNotFound, with: :teams_user_not_found
    team = Team.find(session[:team_id])
  rescue_from ActionController::ParameterMissing, with: :parameter_missing
    @users = team.get_possible_team_members(params[:user][:name])
    render inline: "<%= auto_complete_result @users, 'name' %>", layout: false
  end


   # Example of duties: manager, designer, programmer, tester. Finds TeamsUser and save preferred Duty
   # GET /teams_users
   def update_duties
  # List all the teams_users
     team_user = TeamsUser.find(params[:teams_user_id])
   def index
     team_user.update_attribute(:duty_id, params[:teams_user]['duty_id'])
     teams_users = TeamsUser.all
    redirect_to controller: 'student_teams', action: 'view', student_id: params[:participant_id]
     render json: teams_users, status: :ok
   end
   end


   def list
  # GET /teams/1
     @team = Team.find(params[:id])
  # Get the team_users of a particular team
     @assignment = Assignment.find(@team.parent_id)
   def show
    @teams_users = TeamsUser.page(params[:page]).per_page(10).where(['team_id = ?', params[:id]])
     team = Team.find(params[:id])
     teams_users = TeamsUser.where(team_id: params[:id])
    render json: teams_users, status: :ok
   end
   end


  # GET /teams/1/teams_users/new
  # Render form to create a new teams_user for a specific team
   def new
   def new
     @team = Team.find(params[:id])
     @team = Team.find(params[:id])
    render json: team, status: :ok
   end
   end


  # POST /teams_users
  # Create a new teams_user
   def create
   def create
     user = User.find_by(name: params[:user][:name].strip)
     teams_user = TeamsUser.new(teams_user_params)
     unless user
     if teams_user.save
       urlCreate = url_for controller: 'users', action: 'new'
       render json: teams_user, status: :created
       flash[:error] = "\"#{params[:user][:name].strip}\" is not defined. Please <a href=\"#{urlCreate}\">create</a> this user before continuing."
    else
       render json: { error: teams_user.errors.full_messages }, status: :unprocessable_entity
     end
     end
  end


    team = Team.find(params[:id])
  # PATCH/PUT /teams_users/1
    unless user.nil?
  # Update an existing teams_user
      if team.is_a?(AssignmentTeam)
  def update
        assignment = Assignment.find(team.parent_id)
    if @teams_user.update(teams_user_params)
        if assignment.user_on_team?(user)
       render json: @teams_user, status: :ok
          flash[:error] = "This user is already assigned to a team for this assignment"
    else
          redirect_back fallback_location: root_path
      render json: { error: @teams_user.errors.full_messages }, status: :unprocessable_entity
          return
        end
        if AssignmentParticipant.find_by(user_id: user.id, parent_id: assignment.id).nil?
          urlAssignmentParticipantList = url_for controller: 'participants', action: 'list', id: assignment.id, model: 'Assignment', authorization: 'participant'
          flash[:error] = "\"#{user.name}\" is not a participant of the current assignment. Please <a href=\"#{urlAssignmentParticipantList}\">add</a> this user before continuing."
        else
          begin
            add_member_return = team.add_member(user, team.parent_id)
          rescue
            flash[:error] = "The user #{user.name} is already a member of the team #{team.name}"
            redirect_back fallback_location: root_path
            return
          end
          flash[:error] = 'This team already has the maximum number of members.' if add_member_return == false
          # E2115 Mentor Management
          # Kick off the Mentor Management workflow
          # Note: this is _not_ supported for CourseTeams which is why the other
          # half of this if block does not include the same code
          if add_member_return
            user = TeamsUser.last
            undo_link("The team @teams_user \"#{user.name}\" has been successfully added to \"#{team.name}\".")
            MentorManagement.assign_mentor(assignment.id, team.id)
          end
        end
       else # CourseTeam
        course = Course.find(team.parent_id)
        if course.user_on_team?(user)
          flash[:error] = "This user is already assigned to a team for this course"
          redirect_back fallback_location: root_path
          return
        end
        if CourseParticipant.find_by(user_id: user.id, parent_id: course.id).nil?
          urlCourseParticipantList = url_for controller: 'participants', action: 'list', id: course.id, model: 'Course', authorization: 'participant'
          flash[:error] = "\"#{user.name}\" is not a participant of the current course. Please <a href=\"#{urlCourseParticipantList}\">add</a> this user before continuing."
        else
          begin
            add_member_return = team.add_member(user, team.parent_id)
          rescue
            flash[:error] = "The user #{user.name} is already a member of the team #{team.name}"
            redirect_back fallback_location: root_path
            return
          end
          flash[:error] = 'This team already has the maximum number of members.' if add_member_return == false
          if add_member_return
            @teams_user = TeamsUser.last
            undo_link("The team user \"#{user.name}\" has been successfully added to \"#{team.name}\".")
          end
        end
      end
     end
     end
  end
  # DELETE /teams_users/1
  # Remove a teams_user
  def destroy
    @teams_user = TeamsUser.find(params[:id])


     redirect_to controller: 'teams', action: 'list', id: team.parent_id
     if @teams_user.destroy
      render json: { message: 'TeamsUser removed successfully' }, status: :no_content
    else
      render json: { error: 'Failed to remove TeamsUser' }, status: :unprocessable_entity
    end
   end
   end


   def delete
  private
 
   def find_teams_user
     @teams_user = TeamsUser.find(params[:id])
     @teams_user = TeamsUser.find(params[:id])
    parent_id = Team.find(@teams_user.team_id).parent_id
    @user = User.find(@teams_user.user_id)
    @teams_user.destroy
    undo_link("The team user \"#{@user.name}\" has been successfully removed. ")
    redirect_to controller: 'teams', action: 'list', id: parent_id
   end
   end


   def delete_selected
   def teams_user_params
     params[:item].each do |item_id|
     params.require(:teams_user).permit(:team_id, :user_id, :duty_id, :pair_programming_status, :participant_id)
      team_user = TeamsUser.find(item_id).first
  end
      team_user.destroy
 
     end
  def teams_user_not_found
    render json: { error: "TeamsUser with id #{params[:id]} not found" }, status: :not_found
  end
 
  def parameter_missing
     render json: { error: "Parameter missing" }, status: :unprocessable_entity
  end


     redirect_to action: 'list', id: params[:id]
  def redirect_to_teams_list(parent_id, flash_message)
     redirect_to controller: 'teams', action: 'list', id: parent_id, flash: { success: flash_message }
   end
   end
end
end
Line 261: Line 167:
====Schema====
====Schema====
<pre>
<pre>
   create_table "teams_users", id: :integer, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
   create_table "teams_users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
     t.integer "team_id"
     t.integer "team_id"
     t.integer "user_id"
     t.integer "user_id"
Line 267: Line 173:
     t.string "pair_programming_status", limit: 1
     t.string "pair_programming_status", limit: 1
     t.integer "participant_id"
     t.integer "participant_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
     t.index ["duty_id"], name: "index_teams_participants_on_duty_id"
     t.index ["duty_id"], name: "index_teams_participants_on_duty_id"
     t.index ["participant_id"], name: "fk_rails_f4d20198de"
     t.index ["participant_id"], name: "fk_rails_f4d20198de"
Line 274: Line 182:
</pre>
</pre>


The following image shows the tables referencing teams_users table is referencing to
[[File:teams_users_export.png]]
==Testing Plan==
The TeamsUsers model and controller will be tested using Rspec. As the methods in the controller are defined as RESTful endpoints. The test take into consideration that the methods return the correct status codes for the output. Based on the current functionality of TeamsUsers model and controller we have defined the following test which are implemented to test the reimplemented code of teams_users model and controller.
'''Test cases for teams_users model:'''


===Testing Plan===
The TeamsUsers model and controller will be tested using Rspec. FactoryBot will be utilized to create test fixtures and to build the required models. As the methods in the controller are defined as RESTful endpoints. The test take into consideration that the methods return the correct status codes for the output. Based on the current functionality of TeamsUsers model and controller we have defined the following test which are implemented to test the reimplemented code of teams_users model and controller.


{| class="wikitable" style="margin-left:40px"
{| class="wikitable" style="margin-left:40px"
|-
|-
! Test No. !! Description  
! Test No. !! Name !! Description  
|-
| 1 || Tests if `#update_duties` updates duties for a participant successfully and redirects to '/student_teams/view?student_id=1'.
|-
| 2 || Tests if `#list` renders the list of users under Assignment team teams#users.
|-
| 3 || Tests if `#new` sets the Team object to an instance variable.
|-
| 4 || Tests if `#create` (User Not Defined) throws an error and redirects to 'http://test.host/teams/list?id=1' when a user is not defined.
|-
|-
| 5 || Tests if `#create` (User Not a Participant) throws an error and redirects to 'http://test.host/teams/list?id=1' when the user added is not a participant of the current assignment.
| 1 || `#name` || Verifies that the `name` method of a `TeamsUser` instance returns the name of the associated user.
|-
|-
| 6 || Tests if `#create` (Assignment Team Full) throws an error 'This team already has the maximum number of members.' and redirects to 'http://test.host/teams/list?id=1'.
| 2 || `.remove_team` || Tests the `remove_team` method, ensuring that it removes the corresponding entry in the `TeamsUser` table by creating a `TeamsUser` record, calling `remove_team`, and checking if the entry is removed.
|-
|-
| 7 || Tests if `#create` (User Successfully Added) new user gets successfully added to the assignment and redirects to 'http://test.host/teams/list?id=1'.
| 3 || `.first_by_team_id` || Validates that the `first_by_team_id` method returns the first `TeamsUser` instance associated with a specific team by creating a `TeamsUser` record and checking if the method correctly retrieves it.  
|-
|-
| 8 || Tests if `#delete` deletes a user and redirects to 'http://test.host/teams/list?id=1'.
| 4 || `.team_empty?|| Checks the `team_empty?` method, verifying that it returns `true` if a team has no associated users (empty team), and `false` if there is at least one user associated with the team.
|-
| 9 || Tests if `#delete_selected` deletes selected users and redirects to 'http://test.host/teams_users/list'.
|}
|}




'''Test cases for TeamsUsersController using SwaggerUI:'''


===Relevant Links===
List teams user:
[[File:2386_1.png|1400px]]
 
Create teams user:
[[File:2386_2_2.png|1400px]]
[[File:2386_3.png|1400px]]
 
Added to database on creating:
[[File:2386_4.png|1400px]]
 
Update:
[[File:2386_5.png|1400px]]
[[File:2386_6.png|1400px]]
 
Database after updating:
[[File:2386_7.png|1400px]]
 
Delete:
[[File:2386_8.png|1400px]]
[[File:2386_9.png|1400px]]
 
Database after deleting:
[[File:2386_10.png|1400px]]
 
==Relevant Links==
Github Repository: https://github.com/Kashika08/reimplementation-back-end
Github Repository: https://github.com/Kashika08/reimplementation-back-end


===Team Members===
Pull request: https://github.com/expertiza/reimplementation-back-end/pull/66
 
Video: https://drive.google.com/file/d/1HkfvPSDFRu7zLEhNlopIkfnjAsrwPykp/view?usp=sharing
 
==Team Members==
*Jay Shah (github: jayjshah2000)
*Jay Shah (github: jayjshah2000)


Line 313: Line 245:
*Riya Gori (github: riyagori1203)
*Riya Gori (github: riyagori1203)


===Mentor===
==Mentor==
Kartiki Bhandakkar
Kartiki Bhandakkar

Latest revision as of 04:36, 5 December 2023

Description of Project

The focal point of the project is the teams_users_controller.rb, teams_user.rb model capturing information about team members, and affiliations with other models such as Users and Teams. This model undertakes various responsibilities, including the formation of teams with enrolled students and the display of team members. Oversight of team management falls under the purview of the teams_user_controller, which orchestrates CRUD operations on the teams_user model. Its duties span the creation, modification, and deletion of teams, along with the administration of team members through additions or removals.

Problem Statement

The main aim of the project is to create a backend for teams_users_controller. The team needs to write appropriate test cases for the models as well as refactor the code to make sure the correct JSON response is being returned. The project involves creating a backend system for seamless CRUD operations on a relational database, specifically focusing on interactions between teams and users. This requires defining "teams_users" model with suitable attributes and relationships, establishing controllers to manage CRUD actions, and setting up corresponding routes. Emphasis is placed on rigorous testing, covering model validations and associations, as well as controller actions to ensure accurate execution of CRUD operations. A key project aspect involves refining code to produce precise JSON responses. Adhering to RESTful conventions, the re-implementation includes appropriate HTTP response codes. RSpec tests are mandatory for both the teams_users model and TeamUsersController, covering all endpoints and incorporating HTTP response codes. These controller tests are designed to integrate seamlessly with RSwag for generating API documentation and testing REST APIs through the Swagger UI.

Objectives

  • Craft RESTful endpoints for creating, displaying, updating and deleting teams users.
  • Develop and integrate methods within the teams_users_controller to facilitate CRUD operations
  • Enforce the use of proper status codes and robust validation mechanisms for all RESTful endpoints.
  • Construct models and controllers for the teams_user model, incorporating contemporary approaches to writing Ruby code. This involves leveraging language features and adhering to best practices for object-oriented design.
  • Compose comprehensive RSpec tests covering both the models, and controllers to ensure the robustness and reliability of the entire system.

Development Strategy, Project Design and Implementation

Our development strategy adheres to the principles of Test-Driven Development (TDD) for the implementation of both the teams_user model and the TeamsUsersController. The process begins with the creation of a failing test case, followed by the addition of code to address the identified issues and ensure the successful passage of the test.

We have added the teams_user model and TeamsUserController and have outlined a set of RESTful endpoints along with their corresponding request types for implementation to facilitate CRUD operations on teams_users.

Functionality

In this project, we aim to add functions for the following:

1. Retrieve teams_users of a particular team from the database.

2. Display all teams_users.

3. Add a new teams_user.

4. Update an existing teams_user.

4. Delete a specific teams_user.

Code Snippets

Model

The `TeamsUser` model in the Expertiza code represents a user's association with a team within the context of a collaborative assignment or project. It utilizes ActiveRecord associations to establish relationships with the `User` and `Team` models, indicating that a user belongs to a team. The model includes methods to return the name of the user based on ip_address. Then it includes a method that removes entry in the TeamUsers table for the given user and given team id. Another method returns the first entry in the TeamUsers table for a given team id and the last method determines whether a team is empty or not.


class TeamsUser < ApplicationRecord
  belongs_to :user
  belongs_to :team

  def name(ip_address = nil)
    name = user.name(ip_address)
  end

  def get_team_members(team_id); end

  # Removes entry in the TeamUsers table for the given user and given team id
  def self.remove_team(user_id, team_id)
    team_user = TeamsUser.where('user_id = ? and team_id = ?', user_id, team_id).first
    team_user&.destroy
  end

  # Returns the first entry in the TeamUsers table for a given team id
  def self.first_by_team_id(team_id)
    TeamsUser.where('team_id = ?', team_id).first
  end

  # Determines whether a team is empty of not
  def self.team_empty?(team_id)
    team_members = TeamsUser.where('team_id = ?', team_id)
    team_members.blank?
  end

end

Controller

The `TeamsUsersController` handles various actions related to team management within the application. It includes methods that lists all teams_users, gets the teams_users of a particular team, renders a form to create a new teams_user for a specific team, creates a new teams_user, updates an existing teams_user, removes a teams_user and calls methods on the TeamsUser model.

class Api::V1::TeamsUsersController < ApplicationController
  before_action :find_teams_user, only: [:update, :destroy]


  rescue_from ActiveRecord::RecordNotFound, with: :teams_user_not_found
  rescue_from ActionController::ParameterMissing, with: :parameter_missing

  # GET /teams_users
  # List all the teams_users
  def index
    teams_users = TeamsUser.all
    render json: teams_users, status: :ok
  end

  # GET /teams/1
  # Get the team_users of a particular team
  def show
    team = Team.find(params[:id])
    teams_users = TeamsUser.where(team_id: params[:id])
    render json: teams_users, status: :ok
  end

  # GET /teams/1/teams_users/new
  # Render form to create a new teams_user for a specific team
  def new
    @team = Team.find(params[:id])
    render json: team, status: :ok
  end

  # POST /teams_users
  # Create a new teams_user
  def create
    teams_user = TeamsUser.new(teams_user_params)
    if teams_user.save
      render json: teams_user, status: :created
    else
      render json: { error: teams_user.errors.full_messages }, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /teams_users/1
  # Update an existing teams_user
  def update
    if @teams_user.update(teams_user_params)
      render json: @teams_user, status: :ok
    else
      render json: { error: @teams_user.errors.full_messages }, status: :unprocessable_entity
    end
  end

  # DELETE /teams_users/1
  # Remove a teams_user
  def destroy
    @teams_user = TeamsUser.find(params[:id])

    if @teams_user.destroy
      render json: { message: 'TeamsUser removed successfully' }, status: :no_content
    else
      render json: { error: 'Failed to remove TeamsUser' }, status: :unprocessable_entity
    end
  end

  private

  def find_teams_user
    @teams_user = TeamsUser.find(params[:id])
  end

  def teams_user_params
    params.require(:teams_user).permit(:team_id, :user_id, :duty_id, :pair_programming_status, :participant_id)
  end

  def teams_user_not_found
    render json: { error: "TeamsUser with id #{params[:id]} not found" }, status: :not_found
  end

  def parameter_missing
    render json: { error: "Parameter missing" }, status: :unprocessable_entity
  end

  def redirect_to_teams_list(parent_id, flash_message)
    redirect_to controller: 'teams', action: 'list', id: parent_id, flash: { success: flash_message }
  end
end

Schema

  create_table "teams_users", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
    t.integer "team_id"
    t.integer "user_id"
    t.integer "duty_id"
    t.string "pair_programming_status", limit: 1
    t.integer "participant_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["duty_id"], name: "index_teams_participants_on_duty_id"
    t.index ["participant_id"], name: "fk_rails_f4d20198de"
    t.index ["team_id"], name: "fk_users_teams"
    t.index ["user_id"], name: "fk_teams_users"
  end

The following image shows the tables referencing teams_users table is referencing to

Testing Plan

The TeamsUsers model and controller will be tested using Rspec. As the methods in the controller are defined as RESTful endpoints. The test take into consideration that the methods return the correct status codes for the output. Based on the current functionality of TeamsUsers model and controller we have defined the following test which are implemented to test the reimplemented code of teams_users model and controller.

Test cases for teams_users model:


Test No. Name Description
1 `#name` Verifies that the `name` method of a `TeamsUser` instance returns the name of the associated user.
2 `.remove_team` Tests the `remove_team` method, ensuring that it removes the corresponding entry in the `TeamsUser` table by creating a `TeamsUser` record, calling `remove_team`, and checking if the entry is removed.
3 `.first_by_team_id` Validates that the `first_by_team_id` method returns the first `TeamsUser` instance associated with a specific team by creating a `TeamsUser` record and checking if the method correctly retrieves it.
4 `.team_empty?` Checks the `team_empty?` method, verifying that it returns `true` if a team has no associated users (empty team), and `false` if there is at least one user associated with the team.


Test cases for TeamsUsersController using SwaggerUI:

List teams user:

Create teams user:

Added to database on creating:

Update:

Database after updating:

Delete:

Database after deleting:

Relevant Links

Github Repository: https://github.com/Kashika08/reimplementation-back-end

Pull request: https://github.com/expertiza/reimplementation-back-end/pull/66

Video: https://drive.google.com/file/d/1HkfvPSDFRu7zLEhNlopIkfnjAsrwPykp/view?usp=sharing

Team Members

  • Jay Shah (github: jayjshah2000)
  • Kashika Malick (github: kashika08)
  • Riya Gori (github: riyagori1203)

Mentor

Kartiki Bhandakkar