Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 105 additions & 1 deletion src/researchhub_document/tests/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from hub.tests.helpers import create_hub
from note.tests.helpers import create_note
from paper.tests.helpers import create_paper
from purchase.models import Grant
from purchase.models import Grant, GrantApplication
from purchase.related_models.rsc_exchange_rate_model import RscExchangeRate
from reputation.distributions import Distribution
from reputation.distributor import Distributor
Expand Down Expand Up @@ -1729,3 +1729,107 @@ def test_get_queryset_filters_by_document_type(self):

# Should return no posts
self.assertEqual(len(empty_results), 0)


class PreregistrationGrantAutoAttachTests(APITestCase):
def setUp(self):
self.user = create_random_default_user("prereg_user")
make_user_verified(self.user)
self.hub = create_hub("test_hub")

self.moderator = create_random_default_user("grant_mod")
make_user_verified(self.moderator)
grant_post = create_post(created_by=self.moderator, document_type=GRANT)
self.grant = Grant.objects.create(
created_by=self.moderator,
unified_document=grant_post.unified_document,
amount=Decimal("10000.00"),
currency="USD",
organization="Test Foundation",
description="Test grant",
status=Grant.OPEN,
)

def _create_post(self, document_type="PREREGISTRATION", extra_data=None):
payload = {
"document_type": document_type,
"created_by": self.user.id,
"full_src": "post body content",
"is_public": True,
"renderable_text": "x" * MIN_POST_BODY_LENGTH,
"title": "x" * MIN_POST_TITLE_LENGTH,
"hubs": [self.hub.id],
}
if extra_data:
payload.update(extra_data)
return self.client.post("/api/researchhubpost/", payload)

def test_create_preregistration_with_grant_id_auto_attaches(self):
# Arrange
self.client.force_authenticate(self.user)

# Act
response = self._create_post(extra_data={"grant_id": self.grant.id})

# Assert
self.assertEqual(response.status_code, 200)
self.assertTrue(
GrantApplication.objects.filter(
grant=self.grant,
preregistration_post_id=response.data["id"],
applicant=self.user,
).exists()
)

def test_create_preregistration_without_grant_id_does_not_attach(self):
# Arrange
self.client.force_authenticate(self.user)

# Act
response = self._create_post()

# Assert
self.assertEqual(response.status_code, 200)
self.assertFalse(
GrantApplication.objects.filter(
preregistration_post_id=response.data["id"],
).exists()
)

def test_create_preregistration_with_invalid_grant_id_still_creates_post(self):
# Arrange
self.client.force_authenticate(self.user)

# Act
response = self._create_post(extra_data={"grant_id": 999999})

# Assert
self.assertEqual(response.status_code, 200)
self.assertFalse(GrantApplication.objects.exists())

def test_create_preregistration_with_closed_grant_does_not_attach(self):
# Arrange
self.grant.status = Grant.CLOSED
self.grant.save()
self.client.force_authenticate(self.user)

# Act
response = self._create_post(extra_data={"grant_id": self.grant.id})

# Assert
self.assertEqual(response.status_code, 200)
self.assertFalse(GrantApplication.objects.exists())

def test_grant_id_ignored_for_non_preregistration_types(self):
# Arrange
self.client.force_authenticate(self.user)

# Act
response = self._create_post(
document_type="DISCUSSION",
extra_data={"grant_id": self.grant.id},
)

# Assert
self.assertEqual(response.status_code, 200)
self.assertFalse(GrantApplication.objects.exists())
18 changes: 17 additions & 1 deletion src/researchhub_document/views/researchhub_post_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

from analytics.amplitude import track_event
from discussion.views import ReactionViewActionMixin
from feed.views.grant_cache_mixin import GrantCacheMixin
from hub.models import Hub
from note.related_models.note_model import Note
from purchase.models import Grant
from purchase.models import Grant, GrantApplication
from purchase.related_models.constants.currency import USD
from purchase.serializers.fundraise_create_serializer import FundraiseCreateSerializer
from purchase.serializers.fundraise_serializer import DynamicFundraiseSerializer
Expand All @@ -24,6 +25,7 @@
FILTER_BOUNTY_OPEN,
FILTER_HAS_BOUNTY,
GRANT,
PREREGISTRATION,
RESEARCHHUB_POST_DOCUMENT_TYPES,
SORT_BOUNTY_EXPIRATION_DATE,
SORT_BOUNTY_TOTAL_AMOUNT,
Expand Down Expand Up @@ -115,6 +117,7 @@ def create_researchhub_post(self, request):
assign_doi = data.get("assign_doi", False)
renderable_text = data.get("renderable_text", "")
grant_amount = data.get("grant_amount")
grant_id = data.get("grant_id")

# If a note is provided, check if all given authors are in the same organization
if note_id is not None:
Expand Down Expand Up @@ -267,6 +270,19 @@ def create_researchhub_post(self, request):
)
)

if grant_id and document_type == PREREGISTRATION:
try:
target_grant = Grant.objects.get(id=grant_id)
if target_grant.is_active():
GrantApplication.objects.create(
grant=target_grant,
preregistration_post=rh_post,
applicant=created_by,
)
GrantCacheMixin.invalidate_grant_feed_cache()
except (Grant.DoesNotExist, ValueError, TypeError):
pass

response_data = ResearchhubPostSerializer(rh_post).data
response_data["fundraise"] = (
DynamicFundraiseSerializer(fundraise).data if fundraise else None
Expand Down
Loading