Skip to content
Merged
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
83 changes: 67 additions & 16 deletions backend/api/grants/mutations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import asdict
from enum import Enum
from typing import Annotated, Union, Optional
from participants.models import Participant

from privacy_policy.record import record_privacy_policy_acceptance
import strawberry
Expand Down Expand Up @@ -42,11 +43,13 @@ class _GrantErrors:
notes: list[str] = strawberry.field(default_factory=list)
travelling_from: list[str] = strawberry.field(default_factory=list)
non_field_errors: list[str] = strawberry.field(default_factory=list)
website: list[str] = strawberry.field(default_factory=list)
twitter_handle: list[str] = strawberry.field(default_factory=list)
github_handle: list[str] = strawberry.field(default_factory=list)
linkedin_url: list[str] = strawberry.field(default_factory=list)
mastodon_handle: list[str] = strawberry.field(default_factory=list)
participant_bio: list[str] = strawberry.field(default_factory=list)
participant_website: list[str] = strawberry.field(default_factory=list)
participant_twitter_handle: list[str] = strawberry.field(default_factory=list)
participant_instagram_handle: list[str] = strawberry.field(default_factory=list)
participant_linkedin_url: list[str] = strawberry.field(default_factory=list)
participant_facebook_url: list[str] = strawberry.field(default_factory=list)
participant_mastodon_handle: list[str] = strawberry.field(default_factory=list)

errors: _GrantErrors = None

Expand Down Expand Up @@ -113,11 +116,14 @@ class SendGrantInput(BaseGrantInput):
why: str
notes: str
travelling_from: str
website: str
twitter_handle: str
github_handle: str
linkedin_url: str
mastodon_handle: str

participant_bio: str
participant_website: str
participant_twitter_handle: str
participant_instagram_handle: str
participant_linkedin_url: str
participant_facebook_url: str
participant_mastodon_handle: str

def validate(self, conference: Conference, user: User) -> GrantErrors | None:
errors = super().validate(conference=conference, user=user)
Expand Down Expand Up @@ -147,11 +153,14 @@ class UpdateGrantInput(BaseGrantInput):
why: str
notes: str
travelling_from: str
website: str
twitter_handle: str
github_handle: str
linkedin_url: str
mastodon_handle: str

participant_bio: str
participant_website: str
participant_twitter_handle: str
participant_instagram_handle: str
participant_linkedin_url: str
participant_facebook_url: str
participant_mastodon_handle: str

def validate(self, conference: Conference, user: User) -> GrantErrors | None:
return super().validate(conference=conference, user=user).if_has_errors
Expand Down Expand Up @@ -205,9 +214,23 @@ def send_grant(self, info: Info, input: SendGrantInput) -> SendGrantResult:
with transaction.atomic():
instance = GrantModel.objects.create(
**{
**asdict(input),
"user_id": request.user.id,
"conference": conference,
"name": input.name,
"full_name": input.full_name,
"age_group": input.age_group,
"gender": input.gender,
"occupation": input.occupation,
"grant_type": input.grant_type,
"python_usage": input.python_usage,
"been_to_other_events": input.been_to_other_events,
"community_contribution": input.community_contribution,
"needs_funds_for_travel": input.needs_funds_for_travel,
"need_visa": input.need_visa,
"need_accommodation": input.need_accommodation,
"why": input.why,
"notes": input.notes,
"travelling_from": input.travelling_from,
}
)

Expand All @@ -217,6 +240,20 @@ def send_grant(self, info: Info, input: SendGrantInput) -> SendGrantResult:
"grant",
)

Participant.objects.update_or_create(
user_id=request.user.id,
conference=instance.conference,
defaults={
"bio": input.participant_bio,
"website": input.participant_website,
"twitter_handle": input.participant_twitter_handle,
"instagram_handle": input.participant_instagram_handle,
"linkedin_url": input.participant_linkedin_url,
"facebook_url": input.participant_facebook_url,
"mastodon_handle": input.participant_mastodon_handle,
},
)

# hack because we return django models
instance.__strawberry_definition__ = Grant.__strawberry_definition__
return instance
Expand All @@ -239,6 +276,20 @@ def update_grant(self, info: Info, input: UpdateGrantInput) -> UpdateGrantResult
setattr(instance, attr, value)
instance.save()

Participant.objects.update_or_create(
user_id=request.user.id,
conference=instance.conference,
defaults={
"bio": input.participant_bio,
"website": input.participant_website,
"twitter_handle": input.participant_twitter_handle,
"instagram_handle": input.participant_instagram_handle,
"linkedin_url": input.participant_linkedin_url,
"facebook_url": input.participant_facebook_url,
"mastodon_handle": input.participant_mastodon_handle,
},
)

instance.__strawberry_definition__ = Grant.__strawberry_definition__
return instance

Expand Down
29 changes: 19 additions & 10 deletions backend/api/grants/tests/test_send_grant.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from conferences.tests.factories import ConferenceFactory
from grants.tests.factories import GrantFactory
import pytest
from participants.models import Participant


pytestmark = pytest.mark.django_db

Expand Down Expand Up @@ -35,11 +37,13 @@ def _send_grant(client, conference, conference_code=None, **kwargs):
validationWhy: why
validationNotes: notes
validationTravellingFrom: travellingFrom
validationWebsite: website
validationTwitterHandle: twitterHandle
validationGithubHandle: githubHandle
validationLinkedinUrl: linkedinUrl
validationMastodonHandle: mastodonHandle
validationParticipantBio: participantBio
validationParticipantWebsite: participantWebsite
validationParticipantTwitterHandle: participantTwitterHandle
validationparticipantInstagramHandle: participantInstagramHandle
validationParticipantLinkedinUrl: participantLinkedinUrl
validationParticipantFacebookUrl: participantFacebookUrl
validationParticipantMastodonHandle: participantMastodonHandle
nonFieldErrors
}
}
Expand All @@ -64,11 +68,13 @@ def _send_grant(client, conference, conference_code=None, **kwargs):
"why": grant.why,
"notes": grant.notes,
"travellingFrom": grant.travelling_from,
"website": grant.website,
"twitterHandle": grant.twitter_handle,
"githubHandle": grant.github_handle,
"linkedinUrl": grant.linkedin_url,
"mastodonHandle": grant.mastodon_handle,
"participantBio": "my bio",
"participantWebsite": "http://website.it",
"participantTwitterHandle": "handle",
"participantInstagramHandle": "handleinsta",
"participantLinkedinUrl": "https://linkedin.com/fake-link",
"participantFacebookUrl": "https://facebook.com/fake-link",
"participantMastodonHandle": "[email protected]",
}

variables = {**defaults, **kwargs}
Expand All @@ -87,6 +93,9 @@ def test_send_grant(graphql_client, user):
assert response["data"]["sendGrant"]["__typename"] == "Grant"
assert response["data"]["sendGrant"]["id"]

participant = Participant.objects.get(conference=conference, user_id=user.id)
assert participant.bio == "my bio"

assert PrivacyPolicyAcceptanceRecord.objects.filter(
user=user, conference=conference, privacy_policy="grant"
).exists()
Expand Down
36 changes: 21 additions & 15 deletions backend/api/grants/tests/test_update_grant.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from conferences.tests.factories import ConferenceFactory
from grants.tests.factories import GrantFactory
import pytest
from participants.models import Participant

pytestmark = pytest.mark.django_db

Expand Down Expand Up @@ -34,11 +35,13 @@ def _update_grant(graphql_client, grant, **kwargs):
validationWhy: why
validationNotes: notes
validationTravellingFrom: travellingFrom
validationWebsite: website
validationTwitterHandle: twitterHandle
validationGithubHandle: githubHandle
validationLinkedinUrl: linkedinUrl
validationMastodonHandle: mastodonHandle
validationParticipantBio: participantBio
validationParticipantWebsite: participantWebsite
validationParticipantTwitterHandle: participantTwitterHandle
validationParticipantInstagramHandle: participantInstagramHandle
validationParticipantLinkedinUrl: participantLinkedinUrl
validationParticipantFacebookUrl: participantFacebookUrl
validationparticipantMastodonHandle: participantMastodonHandle
nonFieldErrors
}
}
Expand All @@ -63,11 +66,13 @@ def _update_grant(graphql_client, grant, **kwargs):
"why": grant.why,
"notes": grant.notes,
"travellingFrom": grant.travelling_from,
"website": grant.website,
"twitterHandle": grant.twitter_handle,
"githubHandle": grant.github_handle,
"linkedinUrl": grant.linkedin_url,
"mastodonHandle": grant.mastodon_handle,
"participantBio": "bio",
"participantWebsite": "http://website.it",
"participantTwitterHandle": "handle",
"participantInstagramHandle": "handleinsta",
"participantLinkedinUrl": "https://linkedin.com/fake-link",
"participantFacebookUrl": "https://facebook.com/fake-link",
"participantMastodonHandle": "[email protected]",
}

variables = {
Expand Down Expand Up @@ -105,18 +110,19 @@ def test_update_grant(graphql_client, user):
why="why not",
notes="🧸",
travellingFrom="GB",
website="https://marcotte.house",
twitterHandle="@marcottebear",
githubHandle="marcottebear",
linkedinUrl="www.linkedin.com/in/marcotteba",
mastodonHandle="[email protected]",
participantFacebookUrl="http://facebook.com/pythonpizza",
participantLinkedinUrl="http://linkedin.com/company/pythonpizza",
)

grant.refresh_from_db()

assert not response.get("errors")
assert response["data"]["updateGrant"]["__typename"] == "Grant"

participant = Participant.objects.first()
assert participant.facebook_url == "http://facebook.com/pythonpizza"
assert participant.linkedin_url == "http://linkedin.com/company/pythonpizza"


def test_cannot_update_a_grant_if_user_is_not_owner(
graphql_client,
Expand Down
20 changes: 10 additions & 10 deletions backend/api/grants/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from typing import Optional

import strawberry
from api.participants.types import Participant
from participants.models import Participant as ParticipantModel

from grants.models import Grant as GrantModel

Expand Down Expand Up @@ -33,14 +35,16 @@ class Grant:
notes: str
travelling_from: Optional[str]
applicant_reply_deadline: Optional[datetime]
website: str
twitter_handle: str
github_handle: str
linkedin_url: str
mastodon_handle: str

participant: Participant

@classmethod
def from_model(cls, grant: GrantModel) -> Grant:
participant = ParticipantModel.objects.filter(
user_id=grant.user_id,
conference=grant.conference,
).first()

return cls(
id=grant.id,
status=Status(grant.status),
Expand All @@ -60,9 +64,5 @@ def from_model(cls, grant: GrantModel) -> Grant:
notes=grant.notes,
travelling_from=grant.travelling_from,
applicant_reply_deadline=grant.applicant_reply_deadline,
website=grant.website,
twitter_handle=grant.twitter_handle,
github_handle=grant.github_handle,
linkedin_url=grant.linkedin_url,
mastodon_handle=grant.mastodon_handle,
participant=Participant.from_model(participant),
)
2 changes: 1 addition & 1 deletion backend/api/participants/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Participant:
user_id: ID
bio: str
website: str
photo: str
photo: str | None
photo_id: str | None
public_profile: bool
twitter_handle: str
Expand Down
13 changes: 13 additions & 0 deletions backend/grants/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from helpers.constants import GENDERS
from users.tests.factories import UserFactory
from countries import countries
from participants.tests.factories import ParticipantFactory
from participants.models import Participant


class GrantFactory(DjangoModelFactory):
Expand Down Expand Up @@ -34,3 +36,14 @@ class Meta:
github_handle = factory.Faker("user_name")
linkedin_url = factory.Faker("user_name")
mastodon_handle = factory.Faker("user_name")

@classmethod
def _create(self, model_class, *args, **kwargs):
grant = super()._create(model_class, *args, **kwargs)

if not Participant.objects.filter(
user_id=grant.user.id, conference=grant.conference
).exists():
ParticipantFactory(user_id=grant.user.id, conference=grant.conference)

return grant
1 change: 1 addition & 0 deletions backend/participants/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ParticipantAdmin(admin.ModelAdmin):
form = ParticipantForm
search_fields = ("user__email", "user__full_name")
list_display = (
"id",
"user_display_name",
"conference",
)
Expand Down
Loading
Loading