Skip to content

Commit

Permalink
Project-Teams API tests:
Browse files Browse the repository at this point in the history
- Add projects-teams API endpoint tests
- Fix project teams exceptions and retrieval of user id
  • Loading branch information
d-rita committed Mar 13, 2023
1 parent d7de770 commit d950790
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 12 deletions.
24 changes: 14 additions & 10 deletions backend/api/projects/teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get(self, project_id):
responses:
200:
description: Teams listed successfully
403:
401:
description: Forbidden, if user is not authenticated
404:
description: Not found
Expand All @@ -41,6 +41,8 @@ def get(self, project_id):
try:
teams_dto = TeamService.get_project_teams_as_dto(project_id)
return teams_dto.to_primitive(), 200
except NotFound:
return {"Error": "Project Not Found", "SubCode": "NotFound"}, 404
except Exception as e:
error_msg = f"Team GET - unhandled error: {str(e)}"
current_app.logger.critical(error_msg)
Expand Down Expand Up @@ -85,9 +87,9 @@ def post(self, team_id, project_id):
201:
description: Team project assignment created
401:
description: Forbidden, if user is not a manager of the project
403:
description: Forbidden, if user is not authenticated
403:
description: Forbidden, if user is not a manager of the project or team
404:
description: Not found
500:
Expand All @@ -97,7 +99,7 @@ def post(self, team_id, project_id):
return {
"Error": "User is not an admin or a manager for the team",
"SubCode": "UserPermissionError",
}, 401
}, 403

try:
role = request.get_json(force=True)["role"]
Expand All @@ -107,7 +109,7 @@ def post(self, team_id, project_id):

try:
if not ProjectAdminService.is_user_action_permitted_on_project(
token_auth.current_user, project_id
token_auth.current_user(), project_id
):
raise ValueError()
TeamService.add_team_project(team_id, project_id, role)
Expand All @@ -119,6 +121,8 @@ def post(self, team_id, project_id):
},
201,
)
except NotFound:
return {"Error": "No Project Found", "SubCode": "NotFound"}, 404
except ValueError:
return {
"Error": "User is not a manager of the project",
Expand Down Expand Up @@ -184,11 +188,11 @@ def patch(self, team_id, project_id):

try:
if not ProjectAdminService.is_user_action_permitted_on_project(
token_auth.current_user, project_id
token_auth.current_user(), project_id
):
raise ValueError()
TeamService.change_team_role(team_id, project_id, role)
return {"Status": "Team role updated successfully."}, 200
return {"Status": "Team role updated successfully"}, 200
except NotFound as e:
return {"Error": str(e), "SubCode": "NotFound"}, 404
except ValueError:
Expand Down Expand Up @@ -229,17 +233,17 @@ def delete(self, team_id, project_id):
200:
description: Team unassigned of the project
401:
description: Forbidden, if user is not a manager of the project
403:
description: Forbidden, if user is not authenticated
403:
description: Forbidden, if user is not a manager of the project
404:
description: Not found
500:
description: Internal Server Error
"""
try:
if not ProjectAdminService.is_user_action_permitted_on_project(
token_auth.current_user, project_id
token_auth.current_user(), project_id
):
raise ValueError()
TeamService.delete_team_project(team_id, project_id)
Expand Down
8 changes: 6 additions & 2 deletions backend/services/team_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from backend.models.dtos.stats_dto import Pagination
from backend.models.postgis.message import Message, MessageType
from backend.models.postgis.team import Team, TeamMembers
from backend.models.postgis.project import ProjectTeams
from backend.models.postgis.project import Project, ProjectTeams
from backend.models.postgis.project_info import ProjectInfo
from backend.models.postgis.utils import NotFound
from backend.models.postgis.statuses import (
Expand Down Expand Up @@ -388,8 +388,12 @@ def get_projects_by_team_id(team_id: int):
@staticmethod
def get_project_teams_as_dto(project_id: int) -> TeamsListDTO:
"""Gets all the teams for a specified project"""
project = Project.get(project_id)
if project is None:
raise NotFound()

project_teams = ProjectTeams.query.filter(
ProjectTeams.project_id == project_id
ProjectTeams.project_id == project.id
).all()
teams_list_dto = TeamsListDTO()

Expand Down
238 changes: 238 additions & 0 deletions tests/backend/integration/api/projects/test_teams.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
from tests.backend.base import BaseTestCase
from tests.backend.helpers.test_helpers import (
assign_team_to_project,
create_canned_project,
create_canned_team,
return_canned_user,
generate_encoded_token,
TEST_TEAM_NAME,
)
from backend.models.postgis.statuses import UserRole, TeamRoles


class TestProjectsTeamsAPI(BaseTestCase):
def setUp(self):
super().setUp()
self.test_project, self.test_author = create_canned_project()
self.test_author.role = UserRole.ADMIN.value
self.test_team = create_canned_team()
self.test_user = return_canned_user("test_user", 11111111)
self.test_user.create()
self.test_author_session_token = generate_encoded_token(self.test_author.id)
self.test_user_session_token = generate_encoded_token(self.test_user.id)
self.all_project_teams_url = f"/api/v2/projects/{self.test_project.id}/teams/"
self.single_project_team_url = (
f"/api/v2/projects/{self.test_project.id}/teams/{self.test_team.id}/"
)
self.non_existent_project_team_url = "/api/v2/projects/99/teams/99/"

# get
def test_get_project_teams_by_unauthenticated_user_fails(self):
"""
Test that endpoint returns 401 when an unauthenticated user retrieves teams
"""
response = self.client.get(self.all_project_teams_url)
response_body = response.get_json()
self.assertEqual(response.status_code, 401)
self.assertEqual(response_body["SubCode"], "InvalidToken")

def test_get_project_teams_for_non_existent_project_fails(self):
"""
Test that endpoint returns 404 when retrieving teams for non-existent projects
"""
response = self.client.get(
"/api/v2/projects/99/teams/",
headers={"Authorization": self.test_user_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 404)
self.assertEqual(response_body["Error"], "Project Not Found")
self.assertEqual(response_body["SubCode"], "NotFound")

def test_get_project_teams_passes(self):
"""
Test that endpoint returns 200 when an authenticated user retrieves teams
"""
response = self.client.get(
self.all_project_teams_url,
headers={"Authorization": self.test_user_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response_body["teams"]), 0)
self.assertEqual(response_body["teams"], [])
# setup: add team to project
assign_team_to_project(project=self.test_project, team=self.test_team, role=0)
response = self.client.get(
self.all_project_teams_url,
headers={"Authorization": self.test_user_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response_body["teams"]), 1)
self.assertEqual(response_body["teams"][0]["name"], TEST_TEAM_NAME)
self.assertEqual(response_body["teams"][0]["role"], 0)

# post
def test_assign_team_to_project_by_unauthenticated_user_fails(self):
"""
Test that endpoint returns 401 when unauthenticated user assigns team to project
"""
response = self.client.post(
self.single_project_team_url, json={"role": TeamRoles.MAPPER.name}
)
response_body = response.get_json()
self.assertEqual(response.status_code, 401)
self.assertEqual(response_body["SubCode"], "InvalidToken")

def test_assign_team_to_project_by_non_admin_fails(self):
"""
Test that endpoint returns 403 when non admin assigns team to a project
"""
response = self.client.post(
self.single_project_team_url,
json={"role": TeamRoles.MAPPER.name},
headers={"Authorization": self.test_user_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 403)
self.assertEqual(
response_body["Error"], "User is not an admin or a manager for the team"
)
self.assertEqual(response_body["SubCode"], "UserPermissionError")

def test_assign_team_to_non_existent_project_fails(self):
"""
Test that endpoint returns 404 when admin assigns a team to a non-existent project
"""
response = self.client.post(
f"/api/v2/projects/99/teams/{self.test_team.id}/",
json={"role": TeamRoles.MAPPER.name},
headers={"Authorization": self.test_author_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 404)
self.assertEqual(response_body["Error"], "No Project Found")
self.assertEqual(response_body["SubCode"], "NotFound")

def test_assign_team_to_project_by_admin_passes(self):
"""
Test that endpoint returns 201 when admin successfully assigns a team to a project
"""
response = self.client.post(
self.single_project_team_url,
json={"role": TeamRoles.MAPPER.name},
headers={"Authorization": self.test_author_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 201)
self.assertEqual(
response_body["Success"],
f"Team {self.test_team.id} assigned to project {self.test_project.id} with role MAPPER",
)

# patch
def test_update_team_role_by_unauthenticated_user_fails(self):
"""
Test that endpoint returns 401 when unauthenticated user updates project team role
"""
response = self.client.patch(
self.single_project_team_url, json={"role": TeamRoles.MAPPER.name}
)
response_body = response.get_json()
self.assertEqual(response.status_code, 401)
self.assertEqual(response_body["SubCode"], "InvalidToken")

def test_update_team_role_by_non_admin_fails(self):
"""
Test that endpoint returns 403 when non admin updates project team role
"""
response = self.client.patch(
self.single_project_team_url,
json={"role": TeamRoles.MAPPER.name},
headers={"Authorization": self.test_user_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 403)
self.assertEqual(response_body["Error"], "User is not a manager of the project")
self.assertEqual(response_body["SubCode"], "UserPermissionError")

def test_update_team_role_of_non_existent_project_fails(self):
"""
Test that endpoint returns 404 when admin updates non-existent project team role
"""
response = self.client.patch(
self.non_existent_project_team_url,
json={"role": TeamRoles.MAPPER.name},
headers={"Authorization": self.test_author_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 404)
self.assertEqual(response_body["SubCode"], "NotFound")

def test_update_team_role_by_admin_passes(self):
"""
Test that endpoint returns 200 when admin successfully updates project team role
"""
assign_team_to_project(
self.test_project, self.test_team, TeamRoles.MAPPER.value
)
response = self.client.patch(
self.single_project_team_url,
json={"role": TeamRoles.VALIDATOR.name},
headers={"Authorization": self.test_author_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(response_body["Status"], "Team role updated successfully")

# delete
def test_delete_project_team_by_unauthenticated_user_fails(self):
"""
Test that endpoint returns 401 when unauthenticated user deletes project team
"""
response = self.client.delete(self.single_project_team_url)
response_body = response.get_json()
self.assertEqual(response.status_code, 401)
self.assertEqual(response_body["SubCode"], "InvalidToken")

def test_delete_project_team_by_non_admin_fails(self):
"""
Test that endpoint returns 403 when non admin deletes project team
"""
response = self.client.delete(
self.single_project_team_url,
headers={"Authorization": self.test_user_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 403)
self.assertEqual(response_body["Error"], "User is not a manager of the project")
self.assertEqual(response_body["SubCode"], "UserPermissionError")

def test_delete_non_existent_project_team_fails(self):
"""
Test that endpoint returns 404 when admin deletes non-existent project team
"""
response = self.client.delete(
self.non_existent_project_team_url,
headers={"Authorization": self.test_author_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 404)
self.assertEqual(response_body["Error"], "No team found")
self.assertEqual(response_body["SubCode"], "NotFound")

def test_delete_project_team_by_admin_passes(self):
"""
Test that endpoint returns 200 when admin successfully deletes project team
"""
assign_team_to_project(
self.test_project, self.test_team, TeamRoles.MAPPER.value
)
response = self.client.delete(
self.single_project_team_url,
headers={"Authorization": self.test_author_session_token},
)
response_body = response.get_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(response_body["Success"], True)

0 comments on commit d950790

Please sign in to comment.