CSC/ECE 517 Fall 2023 - E2387. Reimplement Teams backend (Phase 2): Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
 
(26 intermediate revisions by 2 users not shown)
Line 1: Line 1:


== Overview of Expertiza ==
== Project Overview ==
Expertiza is a learning management system that is developed with Ruby on Rails and is accessible as open source software. It can create assignments, tests, assignment teams, and courses, among a wide range of other features and functions. It also has a thorough system for giving other teams and groups of teammates peer reviews and feedback. The files that are largely addressed in this project are the frontend React Components of User, Institution and Roles. A fully functional UI for these components will be developed using React for this project.
===Expertiza Background===
 
Expertiza is an online platform designed to facilitate peer review and submission of various types of academic work, including articles, codes, and websites. The application allows instructors to add assignments, grade them, and assign students to teams based on their topic preferences. The platform also enables students to provide feedback on each other's work through peer reviews, which can be helpful in improving the quality of their projects. Expertiza is backed by the National Science Foundation.
 
===Problem Statement===
The Team model and TeamsController are responsible for managing teams for users and create a team-based assignment system. In this, the system allows the admin to perform CRUD operations on teams model. An admin can create a new team, edit the name of the team, add a student to them team, remove a student from the team, and delete the team. This functinality has to be thoroughly tested and implemented to make sure the code is error-free. The TeamsController includes methods for creating, reading, updating the team name, and deleting the team naem. The create teams page should display all the exisiting teams, with members and their unity ID.
 
==Objectives==
1. Write RESTful endpoints of create, show, update, and delete teams.
 
2. Develop and implement methods in the TeamsController that enable the following functionality: Create teams, show teams, show team members, update team details, delete team, and list all the teams.
 
3. Implement end-points API checks.
 
4. Return proper status codes and proper validation for RESTful endpoints.
 
5. Write models and controllers such that they use modern approaches to writing Ruby code, including utilizing language features and adhering to best practices for object-oriented design.
 
6. Adding relevant data to populate the tables
 
7. Write proper Rspec tests for all APIs, models, controllers.
 


== Technologies Used for the Design ==
== Technologies Used for the Design ==
Line 11: Line 32:
3. Swagger UI
3. Swagger UI


== Changes Made ==
4. React.js in TypeScript for FrontEnd
The Teams schema was not properly implemented and we have added more attributes.  
 
== UI ScreenShots ==
 
'''Overall UI'''
 
[[ File:TeamsFE.jpeg|800px]]
[[ File:TeamsFE 2.jpeg|800px]]
 
'''Adding Teams'''
 
[[ File:CreateTeams.jpeg|800px ]]


[[File:TeamsController_new(present).png]]
'''Adding Users'''


Before Schema
[[File:Add1.jpeg|800px]]
[[File:Add2.jpeg|800px]]


Following attributes would be added to the teams table -
1. Name of the Team (Unique)
2. Team ID (Unique)


[[File:Screenshot from 2023-12-04 16-05-49.png]]
'''Editing Teams'''


Final Schema.
[[ File:EditTeamName.jpeg|800px]]
We also added foreign keys in the Users table as one Team can have many Users
[[File:Editing2.jpeg|800px]]


[[File:UsersUpdated.png]]
'''Deleting Users'''


[[File:Deletion1.jpeg|800px]]
[[File:Deletion2.jpeg|800px]]


'''Deleting Team'''


This will delete the team.
[[File:Deletion1 team.jpeg|800px]]
[[File:Deletion2 team.jpeg|800px]]


== Validations ==
== Validations ==
Line 41: Line 74:


== Design and Implementation ==  
== Design and Implementation ==  
=== Class Diagram ===


[[File: ERDiagram2363Project4.png|500px|]]
[[File: ERDiagram2363Project4.png|500px|]]


=== UML Diagram ===


''' FUNCTIONALITY '''
[[ File:UML teambackend.png |500px]]
 
== Development Strategy ==
We have tried to follow a Test Driven Development approach to implement both the Invitation model and the Invitation Controller.
Firstly a failing test case was written and then the code was added such that the test which was failing will pass now.
 
Also, we have tried to follow the rails philosophy of "Fat models" We have tried to move as much business logic from the controller to the model as possible. This will also help keep the controller code clean and encourage code reusability.
 
== Functionality ==
We also added new controller (teams_controller.rb) in which we added the following methods.
We also added new controller (teams_controller.rb) in which we added the following methods.


Line 61: Line 105:


''' 4. destroy '''
''' 4. destroy '''
This will delete the particular team.
class Api::V1::TeamsController < ApplicationController
  before_action :set_team, only: %i[show update destroy add_ta view_tas remove_ta copy ]
  rescue_from ActionController::ParameterMissing, with: :parameter_missing
  # GET /teams
  # List all the teams
  def index
    teams = Team.order(:id)
    render json: teams, status: :ok
  end
  # GET /teams/1
  # Get a team
  def show
    render json: @team, status: :ok
  end
  # POST /teams
  # Create a team
  def create
    team = Team.new(team_params)
    if team.save
      render json: team, status: :created
    else
      render json: team.errors, status: :unprocessable_entity
    end
  end
  # PATCH/PUT /teams/1
  # Update a team
  def update
    if @team.update(team_params)
      render json: @team, status: :ok
    else
      render json: @team.errors, status: :unprocessable_entity
    end
  end
  # DELETE /teams/1
  # Delete a team
  def destroy
    @team.destroy
    render json: { message: "Team with id #{params[:id]}, deleted" }, status: :no_content
  end
  def set_team
    @team = Team.find(params[:id])
    puts(@team.name)
  end
  def team_params
    params.require(:team).permit(:name)
  end
  def parameter_missing
    render json: { error: 'Parameter missing' }, status: :unprocessable_entity
  end


== End point summary ==
== End point summary ==
Line 67: Line 170:
! Sr No !! Method !! Endpoint !! Request Body !! Description
! Sr No !! Method !! Endpoint !! Request Body !! Description
|-
|-
| 1 || create || POST <br/>/teams||{ <br/> "name": String>} ||Create a new team with given team name.
| 1 || create || POST <br/>/teams||{ "name": String} ||Create a new team with given team name.
|-
|-
| 2 || index || GET <br/>/teams || ||Get a list of all the teams.
| 2 || index || GET <br/>/teams || ||Get a list of all the teams.
Line 73: Line 176:
| 3 || show || GET <br/>/teams/<team_id> || || Get a particular team with the team_id.
| 3 || show || GET <br/>/teams/<team_id> || || Get a particular team with the team_id.
|-
|-
| 4 || update || PATCH /teams/<team_id> || { <br/> "name": String>} || Modify the name of the team.
| 4 || update || PATCH /teams/<team_id> || { "name": String} || Modify the name of the team.
|-
|-
| 5 || destroy || DELETE <br/> /teams/<team_id> || || Delete the team.
| 5 || destroy || DELETE <br/> /teams/<team_id> || || Delete the team.
Line 79: Line 182:
|}
|}


[[ File:DeleteTeam.jpeg||1000px ]]
== Swagger UI ==
 
 
[[ File:UpdateTeam.jpeg||1000px]]
 
 
[[ File:AllTeams.jpeg||1000px]]
 
 
[[ File:AfterCreateTeam.jpeg||1000px ]]
 
[[File:Image.png||1000px]]


[[File:Swagger.jpeg||1000px]]


== Test Plan ==  
== Test Plan ==  
Line 125: Line 218:
|}
|}


[[ File:Tests1 team controller.png ]]  
  require 'rails_helper'
  RSpec.describe 'Teams API', type: :request do
    describe 'GET /teams' do
      context 'when teams exist' do
        let!(:teams) { create_list(:team, 3) }
        it 'returns a list of all teams' do
          get '/teams', as: :json
          expect(response).to have_http_status(:ok)
          expect(response.content_type).to eq('application/json')
          parsed_response = JSON.parse(response.body)
          expect(parsed_response.length).to eq(teams.length)
          team_names = teams.map(&:name)
          returned_team_names = parsed_response.map { |team| team['name'] }
          expect(returned_team_names).to match_array(team_names)
        end
      end
 
      context 'when no teams exist' do
        it 'returns an empty list' do
          get '/teams', as: :json
          expect(response).to have_http_status(:ok)
          expect(response.content_type).to eq('application/json')
          parsed_response = JSON.parse(response.body)
          expect(parsed_response).to be_empty
        end
      end
    end
 
    describe 'POST /api/v1/teams' do
      context 'with valid parameters' do
        it 'creates a new team' do
          team_params = {name: 'New Team'}
          post '/api/v1/teams', params: { team: team_params }, as: :json
          expect(response).to have_http_status(:created)
          expect(response.content_type).to eq('application/json')
          team = Team.last
          expect(JSON.parse(response.body)['id']).to eq(team.id)
        end
      end
    end
 
    describe 'PATCH/PUT /api/v1/teams/:id' do
      let(:team) { create(:team, name: 'Old Team Name') }
      context 'with valid parameters' do
        let(:new_team_name) { 'Updated Team Name' }
        it 'updates the team name' do
          put "/api/v1/teams/#{team.id}", params: { team: { name: new_team_name } }, as: :json
          team.reload
          expect(response).to have_http_status(:ok)
          expect(response.content_type).to eq('application/json')
          expect(JSON.parse(response.body)['id']).to eq(team.id)
          expect(team.name).to eq(new_team_name)
        end
      end
    end
 
    describe 'DELETE /api/v1/teams/:id' do
      let!(:team) { create(:team) }
      it 'deletes a team' do
        expect {
          delete "/api/v1/teams/#{team.id}"
        }.to change(Team, :count).by(-1)
        expect(response).to have_http_status(:no_content)
        expect(response.body).to be_empty
      end
      it 'returns a message indicating team deletion' do
        delete "/api/v1/teams/#{team.id}"
        expect(response).to have_http_status(:no_content)
        expect(response.body).to be_empty
        # Optionally, you can check the response message
        expect(response.body).to eq({ message: "" }.to_json)
      end
    end
  end
 
== Future Work ==
Currently, Some of the methods were not implemented due to dependency on other models which are not implemented yet. So, the major future work would be to include the complete integration of teams and users with the UI.
 
Other work would be to modify the UI for the teams page.
 
== References ==
 
Video Link [https://youtu.be/hhGueZYezSw]
 
Github BE Link [https://github.com/expertiza/reimplementation-back-end]


[[File:Tests2 team controller.png]]
Github FE Link [https://github.com/expertiza/reimplementation-front-end]


[[File:TestsAll.jpeg||1000px]]
Github PR BE Link [https://github.com/expertiza/reimplementation-back-end/pull/61]


Github PR Link
Github PR FE Link [https://github.com/expertiza/reimplementation-front-end/pull/19]


[https://github.com/expertiza/reimplementation-back-end/pull/61]
Rspec [https://rspec.info/documentation/]


Swagger UI [http://localhost:3002/api-docs]


==Team==
==Team==

Latest revision as of 21:17, 11 December 2023

Project Overview

Expertiza Background

Expertiza is an online platform designed to facilitate peer review and submission of various types of academic work, including articles, codes, and websites. The application allows instructors to add assignments, grade them, and assign students to teams based on their topic preferences. The platform also enables students to provide feedback on each other's work through peer reviews, which can be helpful in improving the quality of their projects. Expertiza is backed by the National Science Foundation.

Problem Statement

The Team model and TeamsController are responsible for managing teams for users and create a team-based assignment system. In this, the system allows the admin to perform CRUD operations on teams model. An admin can create a new team, edit the name of the team, add a student to them team, remove a student from the team, and delete the team. This functinality has to be thoroughly tested and implemented to make sure the code is error-free. The TeamsController includes methods for creating, reading, updating the team name, and deleting the team naem. The create teams page should display all the exisiting teams, with members and their unity ID.

Objectives

1. Write RESTful endpoints of create, show, update, and delete teams.

2. Develop and implement methods in the TeamsController that enable the following functionality: Create teams, show teams, show team members, update team details, delete team, and list all the teams.

3. Implement end-points API checks.

4. Return proper status codes and proper validation for RESTful endpoints.

5. Write models and controllers such that they use modern approaches to writing Ruby code, including utilizing language features and adhering to best practices for object-oriented design.

6. Adding relevant data to populate the tables

7. Write proper Rspec tests for all APIs, models, controllers.


Technologies Used for the Design

1. Ruby on Rails

2. Rspec (for Testing)

3. Swagger UI

4. React.js in TypeScript for FrontEnd

UI ScreenShots

Overall UI

Adding Teams

Adding Users


Editing Teams

Deleting Users

Deleting Team

Validations

Only Admins should be able to access this page.

1. Team ID's should be unique.

2. If a team member is already added to another team, it should give appropriate error.

Design and Implementation

Class Diagram

UML Diagram

Development Strategy

We have tried to follow a Test Driven Development approach to implement both the Invitation model and the Invitation Controller. Firstly a failing test case was written and then the code was added such that the test which was failing will pass now.

Also, we have tried to follow the rails philosophy of "Fat models" We have tried to move as much business logic from the controller to the model as possible. This will also help keep the controller code clean and encourage code reusability.

Functionality

We also added new controller (teams_controller.rb) in which we added the following methods.

1. create

This will create a new team.

2. index

This will list all the teams.

3. update

This will update the team's name.

4. destroy This will delete the particular team.

class Api::V1::TeamsController < ApplicationController

 before_action :set_team, only: %i[show update destroy add_ta view_tas remove_ta copy ]
 rescue_from ActionController::ParameterMissing, with: :parameter_missing
 # GET /teams
 # List all the teams
 def index
   teams = Team.order(:id)
   render json: teams, status: :ok
 end
 # GET /teams/1
 # Get a team
 def show
   render json: @team, status: :ok
 end
 # POST /teams
 # Create a team
 def create
   team = Team.new(team_params)
   if team.save
     render json: team, status: :created
   else
     render json: team.errors, status: :unprocessable_entity
   end
 end
 # PATCH/PUT /teams/1
 # Update a team
 def update
   if @team.update(team_params)
     render json: @team, status: :ok
   else
     render json: @team.errors, status: :unprocessable_entity
   end
 end
 # DELETE /teams/1
 # Delete a team
 def destroy
   @team.destroy
   render json: { message: "Team with id #{params[:id]}, deleted" }, status: :no_content
 end
 def set_team
   @team = Team.find(params[:id])
   puts(@team.name)
 end
 def team_params
   params.require(:team).permit(:name)
 end
 def parameter_missing
   render json: { error: 'Parameter missing' }, status: :unprocessable_entity
 end

End point summary

Sr No Method Endpoint Request Body Description
1 create POST
/teams
{ "name": String} Create a new team with given team name.
2 index GET
/teams
Get a list of all the teams.
3 show GET
/teams/<team_id>
Get a particular team with the team_id.
4 update PATCH /teams/<team_id> { "name": String} Modify the name of the team.
5 destroy DELETE
/teams/<team_id>
Delete the team.

Swagger UI

Test Plan

We utilized RSpec as the testing framework for our system and the development process followed Test Driven Development. The controller tests were written in a comprehensive way.

To run the controller tests:

1. git clone

2. cd reimplementation-back-end/

3. bundle install

4. bundle exec rspec spec/requests/api/v1/teams_spec.rb

Sr No Test Description
1 Test to list all Teams This test verifies if the system can successfully retrieve a list of all teams available in the system.
2 Test on empty teams list This test verifies if no teams exist and returns an empty list
3 Test to create a new Team This test verifies if the system can successfully create a new team with valid parameters such as team name
4 Test to update Team Name This test verifies if the system can handle updating team name with valid parameters such as team name.
5 Test to delete a Team This test verifies if the system can team deletion
6 Test to return message indicating team deletion This test returns a message when a team is deleted
 require 'rails_helper'
 RSpec.describe 'Teams API', type: :request do
   describe 'GET /teams' do
     context 'when teams exist' do
       let!(:teams) { create_list(:team, 3) }
       it 'returns a list of all teams' do
         get '/teams', as: :json
         expect(response).to have_http_status(:ok)
         expect(response.content_type).to eq('application/json')
         parsed_response = JSON.parse(response.body)
         expect(parsed_response.length).to eq(teams.length)
         team_names = teams.map(&:name)
         returned_team_names = parsed_response.map { |team| team['name'] }
         expect(returned_team_names).to match_array(team_names)
       end
     end
     context 'when no teams exist' do
       it 'returns an empty list' do
         get '/teams', as: :json
         expect(response).to have_http_status(:ok)
         expect(response.content_type).to eq('application/json')
         parsed_response = JSON.parse(response.body)
         expect(parsed_response).to be_empty
       end
     end
   end
   describe 'POST /api/v1/teams' do
     context 'with valid parameters' do
       it 'creates a new team' do
         team_params = {name: 'New Team'}
         post '/api/v1/teams', params: { team: team_params }, as: :json
         expect(response).to have_http_status(:created)
         expect(response.content_type).to eq('application/json')
         team = Team.last
         expect(JSON.parse(response.body)['id']).to eq(team.id)
       end
     end
   end
   describe 'PATCH/PUT /api/v1/teams/:id' do
     let(:team) { create(:team, name: 'Old Team Name') }
     context 'with valid parameters' do
       let(:new_team_name) { 'Updated Team Name' }
       it 'updates the team name' do
         put "/api/v1/teams/#{team.id}", params: { team: { name: new_team_name } }, as: :json
         team.reload
         expect(response).to have_http_status(:ok)
         expect(response.content_type).to eq('application/json')
         expect(JSON.parse(response.body)['id']).to eq(team.id)
         expect(team.name).to eq(new_team_name)
       end
     end
   end
   describe 'DELETE /api/v1/teams/:id' do
     let!(:team) { create(:team) }
     it 'deletes a team' do
       expect {
         delete "/api/v1/teams/#{team.id}"
       }.to change(Team, :count).by(-1)
       expect(response).to have_http_status(:no_content)
       expect(response.body).to be_empty
     end
     it 'returns a message indicating team deletion' do
       delete "/api/v1/teams/#{team.id}"
       expect(response).to have_http_status(:no_content)
       expect(response.body).to be_empty
       # Optionally, you can check the response message
       expect(response.body).to eq({ message: "" }.to_json)
     end
   end
 end

Future Work

Currently, Some of the methods were not implemented due to dependency on other models which are not implemented yet. So, the major future work would be to include the complete integration of teams and users with the UI.

Other work would be to modify the UI for the teams page.

References

Video Link [1]

Github BE Link [2]

Github FE Link [3]

Github PR BE Link [4]

Github PR FE Link [5]

Rspec [6]

Swagger UI [7]

Team

Mentor
  • Kartiki Bhandakkar <kbhanda3@ncsu.edu>
Members
  • Raghav Narula <rnarula2@ncsu.edu>
  • Mihir Nikam <mvnikam@ncsu.edu>
  • Ebani Gogia <egogia@ncsu.edu>