Skip to content

Commit

Permalink
Change responsibilities of routes and put helper function to find dis…
Browse files Browse the repository at this point in the history
…cussion post in analysis model
  • Loading branch information
JmScherer committed Jan 18, 2024
1 parent a4e9d39 commit fc3d58e
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 60 deletions.
7 changes: 7 additions & 0 deletions backend/src/models/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,10 @@ def units_to_annotate(self):
})

return units

def find_discussion_post(self, discussion_post_id):
for discussion in self.discussions:
if discussion['post_id'] == discussion_post_id:
return discussion

return None
53 changes: 3 additions & 50 deletions backend/src/repository/analysis_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""
from uuid import uuid4

from fastapi import HTTPException, status
from pymongo import ReturnDocument
from ..models.event import Event
from ..enums import EventType
Expand Down Expand Up @@ -499,29 +498,9 @@ def add_discussion_post(self, analysis_name: str, discussion_post: object):

return updated_document['discussions']

def updated_discussion_post(self, discussion_post_id: str, discussion_content: str, client_id: str, analysis_name: str):
def updated_discussion_post(self, discussion_post_id: str, discussion_content: str, analysis_name: str):
""" Edits a discussion post from an analysis to update the discussion post's content """

found_document = self.collection.find_one({"name": analysis_name})

found_document.pop("_id", None)

discussion_post = None

for discussion in found_document['discussions']:
if discussion['post_id'] == discussion_post_id:
discussion_post = discussion
if not discussion['author_id'] == client_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="User cannot edit post they did not author."
)

if discussion_post == None:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Post '{discussion_post_id}' does not exist. Unable to edit discussion post.'"
)

updated_document = self.collection.find_one_and_update(
{"name": analysis_name},
{"$set": { "discussions.$[item].content": discussion_content }},
Expand All @@ -533,35 +512,9 @@ def updated_discussion_post(self, discussion_post_id: str, discussion_content: s

return updated_document['discussions']

def delete_discussion_post(self, discussion_post_id: str, client_id: str, analysis_name: str):
def delete_discussion_post(self, discussion_post_id: str, analysis_name: str):
""" Removes a discussion post from an analysis """

found_document = self.collection.find_one({"name": analysis_name})

if None is found_document:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Analysis '{analysis_name}' does not exist. Unable to delete discussion post.'"
)

found_document.pop("_id", None)

discussion_post = None

for discussion in found_document['discussions']:
if discussion['post_id'] == discussion_post_id:
discussion_post = discussion
if not discussion['author_id'] == client_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="User cannot delete post they did not author."
)

if discussion_post == None:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Post '{discussion_post_id}' does not exist. Unable to delete discussion post.'"
)


updated_document = self.collection.find_one_and_update({"name": analysis_name}, {
"$pull": {"discussions": {"post_id": discussion_post_id}}},
return_document=ReturnDocument.AFTER
Expand Down
64 changes: 55 additions & 9 deletions backend/src/routers/analysis_discussion_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import logging
from uuid import uuid4

from fastapi import (APIRouter, Depends, Form, Security)
from fastapi import (APIRouter, Depends, Form, Security, HTTPException, status)

from ..dependencies import database
from ..models.user import VerifyUser
from ..models.analysis import Analysis
from ..security.security import get_current_user

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -66,22 +67,43 @@ def add_analysis_discussion(

return repositories['analysis'].add_discussion_post(analysis_name, new_discussion_post)

@router.put("/{analysis_name}/discussions")
@router.put("/{analysis_name}/discussions/{discussion_post_id}")
def update_analysis_discussion_post(
analysis_name: str,
discussion_post_id: str = Form(...),
discussion_post_id: str,
discussion_content: str = Form(...),
repositories=Depends(database),
client_id: VerifyUser = Security(get_current_user)
):
logger.info("Editing post '%s' by user '%s' from the analysis '%s' with new content: '%s'",
discussion_post_id, client_id, analysis_name, discussion_content)

return repositories['analysis'].updated_discussion_post(
discussion_post_id, discussion_content, client_id, analysis_name
)

@router.delete("/{analysis_name}/discussions")
found_analysis = repositories['analysis'].find_by_name(analysis_name)

if not found_analysis:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Analysis '{analysis_name}' does not exist. Unable to update discussion post.'"
)

analysis = Analysis(**found_analysis)
discussion_post = analysis.find_discussion_post(discussion_post_id)

if discussion_post == None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Post '{discussion_post_id}' does not exist. Unable to update discussion post.'"
)

if not discussion_post['author_id'] == client_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="User cannot update post they did not author."
)

return repositories['analysis'].updated_discussion_post(discussion_post_id, discussion_content, analysis.name)

@router.delete("/{analysis_name}/discussions/{discussion_post_id}")
def delete_analysis_discussion(
analysis_name: str,
discussion_post_id: str,
Expand All @@ -90,4 +112,28 @@ def delete_analysis_discussion(
):
logger.info("Deleting post %s by user '%s' from the analysis '%s'", discussion_post_id, client_id, analysis_name)

return repositories['analysis'].delete_discussion_post(discussion_post_id, client_id, analysis_name)
found_analysis = repositories['analysis'].find_by_name(analysis_name)

if not found_analysis:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Analysis '{analysis_name}' does not exist. Unable to delete discussion post.'"
)

analysis = Analysis(**found_analysis)
discussion_post = analysis.find_discussion_post(discussion_post_id)

# If the post doesn't exist, then fail
if discussion_post == None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Post '{discussion_post_id}' does not exist. Unable to delete discussion post.'"
)

# Does the post exist and if so, are we the user who posted it?
if not discussion_post['author_id'] == client_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="User cannot delete post they did not author."
)

return repositories['analysis'].delete_discussion_post(discussion_post_id, analysis.name)
30 changes: 29 additions & 1 deletion backend/tests/unit/repository/test_analysis_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def test_remove_section_supporting_evidence(analysis_collection):
def test_add_discussion_post_to_analysis(analysis_collection, cpam0002_analysis_json):
""" Tests adding a user's discussion post to an analysis """

def valid_query_side_effect(*args, **kwargs): # pylint: disable=unused-argument
def valid_query_side_effect(*args, **kwargs): # pylint: disable=unused-argument
find, query = args # pylint: disable=unused-variable
updated_analysis = cpam0002_analysis_json
updated_analysis['discussions'].append(query['$push']['discussions'])
Expand All @@ -406,6 +406,34 @@ def valid_query_side_effect(*args, **kwargs): # pylint: disable=unused-argument

assert actual_most_recent_post == new_post

def test_delete_discussion_post_to_analysis(analysis_collection, cpam0002_analysis_json):
""" Tests deleting a user's discussion post from an analysis by the post's id """

def valid_query_side_effect(*args, **kwargs): # pylint: disable=unused-argument
find, query = args # pylint: disable=unused-variable

print(query)

updated_analysis = cpam0002_analysis_json
# updated_analysis['discussions'].append(query['$push']['discussions'])
updated_analysis['_id'] = 'fake-mongo-object-id'



return updated_analysis

analysis_collection.collection.find_one.return_value = cpam0002_analysis_json
analysis_collection.collection.find_one_and_update.side_effect = valid_query_side_effect

discussion_post_id = "9027ec8d-6298-4afb-add5-6ef710eb5e98"
client_id = "3bghhsmnyqi6uxovazy07ryn9q1tqbnt"
analysis_name = "CPAM0002"

analysis_collection.delete_discussion_post(discussion_post_id, client_id, analysis_name)



assert True == True

@pytest.fixture(name="analysis_with_no_p_dot")
def fixture_analysis_with_no_p_dot():
Expand Down

0 comments on commit fc3d58e

Please sign in to comment.