Skip to content

Commit

Permalink
E2370: Reimplement join team requests controller (expertiza#95)
Browse files Browse the repository at this point in the history
* Reimplement join team requests controller

* Delete swagger.yaml file

* updated join team request controller with requested changes
  • Loading branch information
dinesh-pasupuleti authored Aug 4, 2024
1 parent 94c3c15 commit c060103
Show file tree
Hide file tree
Showing 16 changed files with 386 additions and 4 deletions.
Binary file removed .DS_Store
Binary file not shown.
106 changes: 106 additions & 0 deletions app/controllers/api/v1/join_team_requests_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
class Api::V1::JoinTeamRequestsController < ApplicationController
# Constants used to indicate status for the request
PENDING = 'PENDING'
DECLINED = 'DECLINED'
ACCEPTED = 'ACCEPTED'

# This filter runs before the create action, checking if the team is full
before_action :check_team_status, only: [:create]

# This filter runs before the specified actions, finding the join team request
before_action :find_request, only: %i[show update destroy decline]

#checks if the current user is a student
def action_allowed?
@current_user.student?
end

# GET api/v1/join_team_requests
# gets a list of all the join team requests
def index
unless @current_user.administrator?
return render json: { errors: 'Unauthorized' }, status: :unauthorized
end
join_team_requests = JoinTeamRequest.all
render json: join_team_requests, status: :ok
end

# GET api/v1join_team_requests/1
# show the join team request that is passed into the route
def show
render json: @join_team_request, status: :ok
end

# POST api/v1/join_team_requests
# Creates a new join team request
def create
join_team_request = JoinTeamRequest.new
join_team_request.comments = params[:comments]
join_team_request.status = PENDING
join_team_request.team_id = params[:team_id]
participant = Participant.where(user_id: @current_user.id, assignment_id: params[:assignment_id]).first
team = Team.find(params[:team_id])

if team.participants.include?(participant)
render json: { error: 'You already belong to the team' }, status: :unprocessable_entity
elsif participant
join_team_request.participant_id = participant.id
if join_team_request.save
render json: join_team_request, status: :created
else
render json: { errors: join_team_request.errors.full_messages }, status: :unprocessable_entity
end
else
render json: { errors: 'Participant not found' }, status: :unprocessable_entity
end
end

# PATCH/PUT api/v1/join_team_requests/1
# Updates a join team request
def update
if @join_team_request.update(join_team_request_params)
render json: { message: 'JoinTeamRequest was successfully updated' }, status: :ok
else
render json: { errors: @join_team_request.errors.full_messages }, status: :unprocessable_entity
end
end

# DELETE api/v1/join_team_requests/1
# delete a join team request
def destroy
if @join_team_request.destroy
render json: { message: 'JoinTeamRequest was successfully deleted' }, status: :ok
else
render json: { errors: 'Failed to delete JoinTeamRequest' }, status: :unprocessable_entity
end
end

# decline a join team request
def decline
@join_team_request.status = DECLINED
if @join_team_request.save
render json: { message: 'JoinTeamRequest declined successfully' }, status: :ok
else
render json: { errors: @join_team_request.errors.full_messages }, status: :unprocessable_entity
end
end

private
# checks if the team is full already
def check_team_status
team = Team.find(params[:team_id])
if team.full?
render json: { message: 'This team is full.' }, status: :unprocessable_entity
end
end

# Finds the join team request by ID
def find_request
@join_team_request = JoinTeamRequest.find(params[:id])
end

# Permits specified parameters for join team requests
def join_team_request_params
params.require(:join_team_request).permit(:comments, :status)
end
end
4 changes: 1 addition & 3 deletions app/models/assignment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ class Assignment < ApplicationRecord
belongs_to :instructor, class_name: 'User', inverse_of: :assignments

#This method return the value of the has_badge field for the given assignment object.
attr_accessor :has_badge, :enable_pair_programming, :is_calibrated, :staggered_deadline


attr_accessor :title, :description, :has_badge, :enable_pair_programming, :is_calibrated, :staggered_deadline

def review_questionnaire_id
Questionnaire.find_by_assignment_id id
Expand Down
7 changes: 7 additions & 0 deletions app/models/join_team_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class JoinTeamRequest < ApplicationRecord
# TODO Uncomment the following line when Team and Team Controller is thoroughly implemented
# belongs_to :team
has_one :participant, dependent: :nullify
ACCEPTED_STATUSES = %w[ACCEPTED DECLINED PENDING]
validates :status, inclusion: { in: ACCEPTED_STATUSES }
end
2 changes: 2 additions & 0 deletions app/models/participant.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class Participant < ApplicationRecord
belongs_to :user
belongs_to :assignment, foreign_key: 'assignment_id', inverse_of: false
has_many :join_team_requests, dependent: :destroy
belongs_to :team, optional: true

def fullname
user.fullname
Expand Down
13 changes: 13 additions & 0 deletions app/models/team.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,17 @@ class Team < ApplicationRecord
has_many :users, through: :teams_users
has_many :participants
belongs_to :assignment
attr_accessor :max_participants

# TODO Team implementing Teams controller and model should implement this method better.
# TODO partial implementation here just for the functionality needed for join_team_tequests controller
def full?

max_participants ||= 3
if participants.count >= max_participants
true
else
false
end
end
end
10 changes: 10 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Rails.application.routes.draw do

mount Rswag::Api::Engine => 'api-docs'
mount Rswag::Ui::Engine => 'api-docs'
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
Expand Down Expand Up @@ -69,6 +70,15 @@
post '/sign_up_student', to: 'signed_up_teams#sign_up_student'
end
end

resources :join_team_requests do
collection do
post 'decline/:id', to:'join_team_requests#decline'
end
end



resources :sign_up_topics do
collection do
get :filter
Expand Down
8 changes: 8 additions & 0 deletions db/migrate/20231019170608_create_join_team_requests.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class CreateJoinTeamRequests < ActiveRecord::Migration[7.0]
def change
create_table :join_team_requests do |t|

t.timestamps
end
end
end
8 changes: 8 additions & 0 deletions db/migrate/20231019195109_add_fields_to_join_team_requests.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class AddFieldsToJoinTeamRequests < ActiveRecord::Migration[7.0]
def change
add_column :join_team_requests, :participant_id, :integer
add_column :join_team_requests, :team_id, :integer
add_column :join_team_requests, :comments, :text
add_column :join_team_requests, :status, :string
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddJoinTeamRequestToParticipants < ActiveRecord::Migration[6.0]
def change
add_reference :participants, :join_team_request, foreign_key: true
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class CreateParticipantsTeamsRelationship < ActiveRecord::Migration[7.0]
def change
add_reference :participants, :team, foreign_key: true
end
end
4 changes: 4 additions & 0 deletions spec/factories.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
FactoryBot.define do
factory :join_team_request do

end

factory :user do
sequence(:name) { |_n| Faker::Name.name.to_s.delete(" \t\r\n").downcase }
sequence(:email) { |_n| Faker::Internet.email.to_s }
Expand Down
5 changes: 5 additions & 0 deletions spec/models/join_team_request_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'rails_helper'

RSpec.describe JoinTeamRequest, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end
176 changes: 176 additions & 0 deletions spec/requests/api/v1/join_team_requests_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
require 'swagger_helper'

RSpec.describe 'Join Team Requests Controller', type: :request do

# API endpoint to decline a join team request
path '/api/v1/join_team_requests/decline/{id}' do
parameter name: 'id', in: :path, type: :string, description: 'id'

post('decline join_team_request') do
tags 'Join Team Requests'
response(200, 'successful') do
# Include response example in Swagger documentation
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test!
end
end
end

# API endpoint to list join team requests
path '/api/v1/join_team_requests' do

get('list join_team_requests') do
tags 'Join Team Requests'
response(200, 'successful') do
# Include response example in Swagger documentation
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test!
end
end

# API endpoint to create a join team request
post('create join_team_request') do
parameter name: 'comments', in: :query, type: :string, description: 'comments'
parameter name: 'team_id', in: :query, type: :integer, description: 'team_id'
parameter name: 'assignment_id', in: :query, type: :integer, description: 'assignment_id'
tags 'Join Team Requests'

# Success response
response(200, 'success') do
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test!
end

# Created response with example data
response(201, 'created') do
let(:join_team_request) { JoinTeamRequest.create(valid_join_team_request_params) }
run_test! do
expect(response.body).to include('"comments":"comment"')
end
end

# Unprocessable Entity response with example data
response(422, 'unprocessable entity') do
let(:join_team_request) { JoinTeamRequest.create(invalid_join_team_request_params) }
run_test!
end
end
end

# API endpoint to show a specific join team request
path '/api/v1/join_team_requests/{id}' do
parameter name: 'id', in: :path, type: :string, description: 'id'

get('show join_team_request') do
tags 'Join Team Requests'
response(200, 'successful') do
# Include response example in Swagger documentation
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
# 404 response when the requested join team request is not found
response(404, 'not_found') do
let(:id) { 'invalid' }
run_test! do
expect(response.body).to include("Couldn't find JoinTeamRequest")
end
end
run_test!
end
end

# API endpoint to update a join team request using PATCH
patch('update join_team_request') do
parameter name: 'join_team_request[comments]', in: :query, type: :string, description: 'comments'
parameter name: 'join_team_request[status]', in: :query, type: :string, description: 'status'
tags 'Join Team Requests'
response(200, 'successful') do
# Include response example in Swagger documentation
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test!
end
end

# API endpoint to update a join team request using PUT
put('update join_team_request') do
parameter name: 'join_team_request[comments]', in: :query, type: :string, description: 'comments'
parameter name: 'join_team_request[status]', in: :query, type: :string, description: 'status'
tags 'Join Team Requests'

# Include request body parameter schema in Swagger documentation
parameter name: :body_params, in: :body, schema: {
type: :object,
properties: {
comments: { type: :string }
}
}
response(200, 'successful') do
# Include response example in Swagger documentation
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test!
end

# Unprocessable Entity response with example data
response(422, 'unprocessable entity') do
let(:body_params) { { comments: -1 } }
schema type: :string
run_test! do
expect(response.body).to_not include('"comments":-1')
end
end
end

# API endpoint to delete a join team request
delete('delete join_team_request') do
tags 'Join Team Requests'

# Successful response with example
response(204, 'successful') do
run_test! do
expect(JoinTeamRequest.exists?(id)).to eq(false)
end
end

# Not Found response with example
response(404, 'not found') do
run_test! do
expect(response.body).to include("Couldn't find JoinTeamRequest")
end
end
end
end
end
Loading

0 comments on commit c060103

Please sign in to comment.