diff --git a/src/researchhub_document/tests/test_view.py b/src/researchhub_document/tests/test_view.py index b03bf58d7..2d4068cde 100644 --- a/src/researchhub_document/tests/test_view.py +++ b/src/researchhub_document/tests/test_view.py @@ -35,7 +35,7 @@ def setUp(self): object_id=self.organization.id, user=self.member_user, ) - + self.hub = create_hub("hub") def test_author_can_delete_doc(self): @@ -51,8 +51,8 @@ def test_author_can_delete_doc(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) @@ -80,8 +80,8 @@ def test_author_can_restore_doc(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) @@ -110,8 +110,8 @@ def test_moderator_can_restore_doc(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) @@ -141,8 +141,8 @@ def test_non_author_cannot_delete_doc(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) @@ -173,8 +173,8 @@ def test_moderator_can_delete_doc(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) @@ -204,14 +204,56 @@ def test_author_can_create_post(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) self.assertEqual(doc_response.status_code, 200) + def test_min_post_title_length(self): + author = create_random_default_user("author") + hub = create_hub() + + self.client.force_authenticate(author) + + doc_response = self.client.post( + "/api/researchhubpost/", + { + "document_type": "DISCUSSION", + "created_by": author.id, + "full_src": "body", + "is_public": True, + "renderable_text": "body", + "title": "short title", + "hubs": [hub.id], + }, + ) + + self.assertEqual(doc_response.status_code, 400) + + def test_min_post_body_length(self): + author = create_random_default_user("author") + hub = create_hub() + + self.client.force_authenticate(author) + + doc_response = self.client.post( + "/api/researchhubpost/", + { + "document_type": "DISCUSSION", + "created_by": author.id, + "full_src": "body", + "is_public": True, + "renderable_text": "short body", + "title": "long title long title long title", + "hubs": [hub.id], + }, + ) + + self.assertEqual(doc_response.status_code, 400) + def test_user_can_create_post_with_multiple_authors(self): note = create_note(self.admin_user, self.organization) @@ -227,8 +269,8 @@ def test_user_can_create_post_with_multiple_authors(self): "hubs": [self.hub.id], "is_public": True, "note_id": note[0].id, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", }, ) @@ -249,8 +291,8 @@ def test_user_cannot_create_post_with_non_members(self): "hubs": [self.hub.id], "is_public": True, "note_id": note[0].id, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", }, ) @@ -269,8 +311,8 @@ def test_author_can_update_post(self): "full_src": "body", "is_public": True, "note_id": note[0].id, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [self.hub.id], }, ) @@ -281,17 +323,20 @@ def test_author_can_update_post(self): "/api/researchhubpost/", { "post_id": doc_response.data["id"], - "title": "updated title", "document_type": "DISCUSSION", "created_by": self.admin_user.id, "full_src": "body", "is_public": True, - "renderable_text": "body", + "title": "updated title. updated title. updated title.", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", "hubs": [self.hub.id], }, ) - self.assertEqual(updated_response.data["title"], "updated title") + self.assertEqual( + updated_response.data["title"], + "updated title. updated title. updated title.", + ) def test_author_cannot_update_post_with_non_members(self): note = create_note(self.admin_user, self.organization) @@ -306,8 +351,8 @@ def test_author_cannot_update_post_with_non_members(self): "full_src": "body", "is_public": True, "note_id": note[0].id, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [self.hub.id], }, ) @@ -319,12 +364,12 @@ def test_author_cannot_update_post_with_non_members(self): { "authors": [self.admin_author.id, self.non_member_author.id], "post_id": doc_response.data["id"], - "title": "updated title", "document_type": "DISCUSSION", "created_by": self.admin_user.id, "full_src": "body", "is_public": True, - "renderable_text": "body", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [self.hub.id], }, ) @@ -347,8 +392,8 @@ def test_non_author_cannot_update_post(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], "note_id": note[0].id, }, @@ -361,106 +406,16 @@ def test_non_author_cannot_update_post(self): "/api/researchhubpost/", { "post_id": doc_response.data["id"], - "title": "updated title", "document_type": "DISCUSSION", "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "hubs": [hub.id], - }, - ) - - self.assertEqual(updated_response.status_code, 403) - - def test_author_can_create_hypothesis(self): - author = create_random_default_user("author") - hub = create_hub() - - self.client.force_authenticate(author) - - doc_response = self.client.post( - "/api/hypothesis/", - { - "document_type": "HYPOTHESIS", - "created_by": author.id, - "full_src": "body", - "is_public": True, - "renderable_text": "body", - "title": "hypothesis", - "hubs": [hub.id], - }, - ) - - self.assertEqual(doc_response.status_code, 200) - - def test_author_can_update_hypothesis(self): - author = create_random_default_user("author") - hub = create_hub() - - self.client.force_authenticate(author) - - doc_response = self.client.post( - "/api/hypothesis/", - { - "document_type": "HYPOTHESIS", - "created_by": author.id, - "full_src": "body", - "is_public": True, - "renderable_text": "body", - "title": "title", - "hubs": [hub.id], - }, - ) - self.assertEqual(doc_response.status_code, 200) - - updated_response = self.client.post( - f"/api/hypothesis/{doc_response.data['id']}/upsert/", - { - "hypothesis_id": doc_response.data["id"], - "title": "updated title", - "document_type": "HYPOTHESIS", - "full_src": "updated body", - "renderable_text": "body", - }, - ) - self.assertEqual(updated_response.status_code, 200) - self.assertEqual(updated_response.data["full_markdown"], "updated body") - - def test_non_author_cannot_edit_hypothesis(self): - author = create_random_default_user("author") - non_author = create_random_default_user("non_author") - hub = create_hub() - - self.client.force_authenticate(author) - - doc_response = self.client.post( - "/api/hypothesis/", - { - "document_type": "HYPOTHESIS", - "created_by": author.id, - "full_src": "body", - "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) - self.assertEqual(doc_response.status_code, 200) - self.client.force_authenticate(non_author) - - updated_response = self.client.post( - f"/api/hypothesis/{doc_response.data['id']}/upsert/", - { - "hypothesis_id": doc_response.data["id"], - "title": "updated title", - "document_type": "HYPOTHESIS", - "full_src": "updated body", - "renderable_text": "body", - }, - ) - self.assertEqual(updated_response.status_code, 403) self.assertEqual(updated_response.status_code, 403) def test_hub_editors_can_censor_papers(self): @@ -529,8 +484,8 @@ def test_register_doi_with_sufficient_funds(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) @@ -557,8 +512,8 @@ def test_register_doi_with_insufficient_funds(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) @@ -585,8 +540,8 @@ def test_no_doi_with_sufficient_funds(self): "created_by": author.id, "full_src": "body", "is_public": True, - "renderable_text": "body", - "title": "title", + "renderable_text": "sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body. sufficiently long body", + "title": "sufficiently long title. sufficiently long title.", "hubs": [hub.id], }, ) diff --git a/src/researchhub_document/views/researchhub_post_views.py b/src/researchhub_document/views/researchhub_post_views.py index d7f5b270c..e8c27c171 100644 --- a/src/researchhub_document/views/researchhub_post_views.py +++ b/src/researchhub_document/views/researchhub_post_views.py @@ -62,6 +62,9 @@ from utils.siftscience import SIFT_POST, sift_track from utils.throttles import THROTTLE_CLASSES +MIN_POST_TITLE_LENGTH = 20 +MIN_POST_BODY_LENGTH = 50 + class ResearchhubPostViewSet(ReactionViewActionMixin, ModelViewSet): ordering = "-created_date" @@ -113,6 +116,12 @@ def create_researchhub_post(self, request): data = request.data authors = data.get("authors", []) note_id = data.get("note_id", None) + document_type = data.get("document_type") + editor_type = data.get("editor_type") + title = data.get("title", "") + assign_doi = data.get("assign_doi", False) + peer_review_is_requested = data.get("request_peer_review", False) + renderable_text = data.get("renderable_text", "") # If a note is provided, check if all given authors are in the same organization if note_id is not None: @@ -123,14 +132,27 @@ def create_researchhub_post(self, request): "No permission to create note for organization", status=403 ) + if type(title) is not str or len(title) < MIN_POST_TITLE_LENGTH: + return Response( + { + "msg": f"Title cannot be less than {MIN_POST_TITLE_LENGTH} characters" + }, + 400, + ) + elif ( + type(renderable_text) is not str + or len(renderable_text) < MIN_POST_BODY_LENGTH + ): + return Response( + { + "msg": f"Post body cannot be less than {MIN_POST_BODY_LENGTH} characters" + }, + 400, + ) + try: with transaction.atomic(): created_by = request.user - document_type = data.get("document_type") - editor_type = data.get("editor_type") - title = data.get("title", "") - assign_doi = data.get("assign_doi", False) - peer_review_is_requested = data.get("request_peer_review", False) doi = generate_doi() if assign_doi else None if assign_doi and created_by.get_balance() - CROSSREF_DOI_RSC_FEE < 0: @@ -225,10 +247,29 @@ def update_existing_researchhub_posts(self, request): created_by = request.user hubs = data.pop("hubs", None) + renderable_text = data.pop("renderable_text", "") title = data.get("title", "") assign_doi = data.get("assign_doi", False) doi = generate_doi() if assign_doi else None + if type(title) is not str or len(title) < MIN_POST_TITLE_LENGTH: + return Response( + { + "msg": f"Title cannot be less than {MIN_POST_TITLE_LENGTH} characters" + }, + 400, + ) + elif ( + type(renderable_text) is not str + or len(renderable_text) < MIN_POST_BODY_LENGTH + ): + return Response( + { + "msg": f"Post body cannot be less than {MIN_POST_BODY_LENGTH} characters" + }, + 400, + ) + if assign_doi and created_by.get_balance() - CROSSREF_DOI_RSC_FEE < 0: return Response("Insufficient Funds", status=402)