diff --git a/backend/api/cms/tests/factories.py b/backend/api/cms/tests/factories.py index c21e38d4b4..9cba3aafe7 100644 --- a/backend/api/cms/tests/factories.py +++ b/backend/api/cms/tests/factories.py @@ -15,13 +15,13 @@ StreamFieldFactory, SiteFactory, ) +from wagtail.models import Site import factory from decimal import Decimal from pytest_factoryboy import register from wagtail.rich_text import RichText -register(SiteFactory) register(PageFactory) @@ -92,3 +92,18 @@ class GenericPageFactory(PageFactory): class Meta: model = GenericPage + + +@register +class SiteFactory(SiteFactory): + """ + Overrides wagtail_factories.SiteFactory to use "testserver" as hostname + to make sure it works with Wagtail's ALLOWED_HOSTS in test environments. + """ + + hostname = "testserver" + root_page = factory.SubFactory(GenericPageFactory) + is_default_site = True + + class Meta: + model = Site diff --git a/backend/api/conferences/types.py b/backend/api/conferences/types.py index 7aaa7f18fa..d3d16eda1f 100644 --- a/backend/api/conferences/types.py +++ b/backend/api/conferences/types.py @@ -246,7 +246,6 @@ class Conference: map: Optional[Map] = strawberry.field(resolver=resolve_map) pretix_event_url: str - visa_application_form_link: str @strawberry.field def voucher(self, info, code: str) -> Optional[Voucher]: diff --git a/backend/conferences/admin.py b/backend/conferences/admin.py index f33133b967..0fc971f2a3 100644 --- a/backend/conferences/admin.py +++ b/backend/conferences/admin.py @@ -162,7 +162,6 @@ class ConferenceAdmin(OrderedInlineModelAdminMixin, admin.ModelAdmin): "topics", "audience_levels", "languages", - "visa_application_form_link", ) }, ), diff --git a/backend/conferences/migrations/0041_remove_conference_visa_application_form_link.py b/backend/conferences/migrations/0041_remove_conference_visa_application_form_link.py new file mode 100644 index 0000000000..8025dfc423 --- /dev/null +++ b/backend/conferences/migrations/0041_remove_conference_visa_application_form_link.py @@ -0,0 +1,16 @@ +# Generated by Django 4.2.7 on 2024-02-13 13:46 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("conferences", "0040_conference_visa_application_form_link"), + ] + + operations = [ + migrations.RemoveField( + model_name="conference", + name="visa_application_form_link", + ), + ] diff --git a/backend/conferences/models/conference.py b/backend/conferences/models/conference.py index ee73cbb71a..a6ebacdb2d 100644 --- a/backend/conferences/models/conference.py +++ b/backend/conferences/models/conference.py @@ -133,10 +133,6 @@ class Conference(GeoLocalizedModel, TimeFramedModel, TimeStampedModel): default=None, ) - visa_application_form_link = models.URLField( - _("Visa application form link"), blank=True, default="" - ) - youtube_video_bottom_text = models.TextField( default="", blank=True, diff --git a/backend/conferences/tests/factories.py b/backend/conferences/tests/factories.py index 524c19cf39..ce202c50f8 100644 --- a/backend/conferences/tests/factories.py +++ b/backend/conferences/tests/factories.py @@ -34,7 +34,6 @@ class ConferenceFactory(DjangoModelFactory): pretix_organizer_id = "base-pretix-organizer-id" pretix_event_id = "base-pretix-event-id" - visa_application_form_link = factory.Faker("url") @classmethod def _create(cls, model_class, *args, **kwargs): diff --git a/backend/grants/admin.py b/backend/grants/admin.py index 6e949e4dae..9e7c654ae2 100644 --- a/backend/grants/admin.py +++ b/backend/grants/admin.py @@ -201,16 +201,6 @@ def wrapper(modeladmin, request, queryset): @admin.action(description="Send Approved/Waiting List/Rejected reply emails") @validate_single_conference_selection def send_reply_emails(modeladmin, request, queryset): - conference = queryset.first().conference - - if not conference.visa_application_form_link: - messages.error( - request, - "Visa Application Form Link Missing: Please ensure the link to the Visa " - "Application Form is set in the Conference admin settings.", - ) - return - queryset = queryset.filter( status__in=( Grant.Status.approved, diff --git a/backend/grants/tasks.py b/backend/grants/tasks.py index c8a9a9af83..c47a21b4a4 100644 --- a/backend/grants/tasks.py +++ b/backend/grants/tasks.py @@ -31,12 +31,6 @@ def send_grant_reply_approved_email(*, grant_id, is_reminder): "Reminder: Financial Aid Update" if is_reminder else "Financial Aid Update" ) - if not grant.conference.visa_application_form_link: - raise ValueError( - "Visa Application Form Link Missing: Please ensure the link to the Visa " - "Application Form is set in the Conference admin settings." - ) - template = EmailTemplate.GRANT_APPROVED variables = { "replyLink": reply_url, @@ -44,7 +38,7 @@ def send_grant_reply_approved_email(*, grant_id, is_reminder): "endDate": f"{grant.conference.end+timedelta(days=1):%-d %B}", "deadlineDateTime": f"{grant.applicant_reply_deadline:%-d %B %Y %H:%M %Z}", "deadlineDate": f"{grant.applicant_reply_deadline:%-d %B %Y}", - "visaApplicationFormLink": grant.conference.visa_application_form_link, + "visaPageLink": urljoin(settings.FRONTEND_URL, "/visa"), "hasApprovedTravel": grant.has_approved_travel(), "hasApprovedAccommodation": grant.has_approved_accommodation(), } @@ -151,6 +145,8 @@ def send_grant_voucher_email(*, grant_id): variables={ "firstname": get_name(user, "there"), "voucherCode": voucher_code, + "hasApprovedAccommodation": grant.has_approved_accommodation(), + "visaPageLink": urljoin(settings.FRONTEND_URL, "/visa"), }, reply_to=[ "grants@pycon.it", diff --git a/backend/grants/tests/test_admin.py b/backend/grants/tests/test_admin.py index bcdd36ab20..b34443fa21 100644 --- a/backend/grants/tests/test_admin.py +++ b/backend/grants/tests/test_admin.py @@ -12,11 +12,15 @@ ) from grants.models import Grant + pytestmark = pytest.mark.django_db def test_send_reply_emails_with_grants_from_multiple_conferences( - rf, grant_factory, mocker, conference_factory + rf, + grant_factory, + mocker, + conference_factory, ): """ Test that sending reply emails does not proceed when selected grants belong @@ -79,7 +83,6 @@ def test_send_reply_emails_approved_missing_amount(rf, grant_factory, mocker): status=Grant.Status.approved, approved_type=Grant.ApprovedType.ticket_accommodation, total_amount=None, - conference__visa_application_form_link="https://forms.com/visa", ) grant.total_amount = None grant.save() @@ -105,7 +108,6 @@ def test_send_reply_emails_approved_set_deadline_in_fourteen_days( status=Grant.Status.approved, approved_type=Grant.ApprovedType.ticket_accommodation, total_amount=800, - conference__visa_application_form_link="https://forms.com/visa", ) request = rf.get("/") mock_send_approved_email = mocker.patch( diff --git a/backend/grants/tests/test_tasks.py b/backend/grants/tests/test_tasks.py index 23c35968a5..d01aff315c 100644 --- a/backend/grants/tests/test_tasks.py +++ b/backend/grants/tests/test_tasks.py @@ -23,6 +23,7 @@ def test_send_grant_voucher_email(settings, grant_factory): + settings.FRONTEND_URL = "https://pycon.it" user = UserFactory( full_name="Marco Acierno", email="marco@placeholder.it", @@ -33,6 +34,7 @@ def test_send_grant_voucher_email(settings, grant_factory): grant = grant_factory( user=user, voucher_code="ABC123", + approved_type=Grant.ApprovedType.ticket_only, ) with patch("grants.tasks.send_email") as email_mock: @@ -45,6 +47,8 @@ def test_send_grant_voucher_email(settings, grant_factory): variables={ "firstname": "Marco Acierno", "voucherCode": "ABC123", + "hasApprovedAccommodation": False, + "visaPageLink": "https://pycon.it/visa", }, reply_to=["grants@pycon.it"], ) @@ -118,7 +122,6 @@ def test_handle_grant_reply_sent_reminder(conference_factory, grant_factory, set conference = conference_factory( start=datetime(2023, 5, 2, tzinfo=timezone.utc), end=datetime(2023, 5, 5, tzinfo=timezone.utc), - visa_application_form_link="https://example.com/visa-application-form", ) user = UserFactory( full_name="Marco Acierno", @@ -149,7 +152,7 @@ def test_handle_grant_reply_sent_reminder(conference_factory, grant_factory, set "deadlineDateTime": "1 February 2023 23:59 UTC", "deadlineDate": "1 February 2023", "replyLink": "https://pycon.it/grants/reply/", - "visaApplicationFormLink": "https://example.com/visa-application-form", + "visaPageLink": "https://pycon.it/visa", "hasApprovedTravel": False, "hasApprovedAccommodation": False, }, @@ -165,7 +168,6 @@ def test_handle_grant_approved_ticket_travel_accommodation_reply_sent( conference = conference_factory( start=datetime(2023, 5, 2, tzinfo=timezone.utc), end=datetime(2023, 5, 5, tzinfo=timezone.utc), - visa_application_form_link="https://example.com/visa-application-form", ) user = UserFactory( full_name="Marco Acierno", @@ -198,7 +200,7 @@ def test_handle_grant_approved_ticket_travel_accommodation_reply_sent( "deadlineDateTime": "1 February 2023 23:59 UTC", "deadlineDate": "1 February 2023", "replyLink": "https://pycon.it/grants/reply/", - "visaApplicationFormLink": "https://example.com/visa-application-form", + "visaPageLink": "https://pycon.it/visa", "hasApprovedTravel": True, "hasApprovedAccommodation": True, }, @@ -214,7 +216,6 @@ def test_handle_grant_approved_ticket_travel_accommodation_fails_with_no_amount( conference = conference_factory( start=datetime(2023, 5, 2, tzinfo=timezone.utc), end=datetime(2023, 5, 5, tzinfo=timezone.utc), - visa_application_form_link="https://example.com/visa-application-form", ) user = UserFactory( full_name="Marco Acierno", @@ -237,33 +238,6 @@ def test_handle_grant_approved_ticket_travel_accommodation_fails_with_no_amount( send_grant_reply_approved_email(grant_id=grant.id, is_reminder=False) -def test_handle_grant_approved_ticket_fails_with_no_visa_application_form_link( - conference_factory, grant_factory, settings -): - settings.FRONTEND_URL = "https://pycon.it" - - conference = conference_factory( - start=datetime(2023, 5, 2, tzinfo=timezone.utc), - end=datetime(2023, 5, 5, tzinfo=timezone.utc), - visa_application_form_link="", - ) - user = UserFactory() - grant = grant_factory( - conference=conference, - approved_type=Grant.ApprovedType.ticket_travel_accommodation, - applicant_reply_deadline=datetime(2023, 2, 1, 23, 59, tzinfo=timezone.utc), - travel_amount=0, - user=user, - ) - - with pytest.raises( - ValueError, - match="Visa Application Form Link Missing: Please ensure the link to the Visa " - "Application Form is set in the Conference admin settings.", - ): - send_grant_reply_approved_email(grant_id=grant.id, is_reminder=False) - - def test_handle_grant_approved_ticket_only_reply_sent( conference_factory, grant_factory, settings ): @@ -272,7 +246,6 @@ def test_handle_grant_approved_ticket_only_reply_sent( conference = conference_factory( start=datetime(2023, 5, 2, tzinfo=timezone.utc), end=datetime(2023, 5, 5, tzinfo=timezone.utc), - visa_application_form_link="https://example.com/visa-application-form", ) user = UserFactory( full_name="Marco Acierno", @@ -304,7 +277,7 @@ def test_handle_grant_approved_ticket_only_reply_sent( "deadlineDateTime": "1 February 2023 23:59 UTC", "deadlineDate": "1 February 2023", "replyLink": "https://pycon.it/grants/reply/", - "visaApplicationFormLink": "https://example.com/visa-application-form", + "visaPageLink": "https://pycon.it/visa", "hasApprovedTravel": False, "hasApprovedAccommodation": False, }, @@ -320,7 +293,6 @@ def test_handle_grant_approved_travel_reply_sent( conference = conference_factory( start=datetime(2023, 5, 2, tzinfo=timezone.utc), end=datetime(2023, 5, 5, tzinfo=timezone.utc), - visa_application_form_link="https://example.com/visa-application-form", ) user = UserFactory( full_name="Marco Acierno", @@ -353,7 +325,7 @@ def test_handle_grant_approved_travel_reply_sent( "deadlineDateTime": "1 February 2023 23:59 UTC", "deadlineDate": "1 February 2023", "replyLink": "https://pycon.it/grants/reply/", - "visaApplicationFormLink": "https://example.com/visa-application-form", + "visaPageLink": "https://pycon.it/visa", "hasApprovedTravel": True, "hasApprovedAccommodation": False, "amount": "400", diff --git a/email-templates/src/templates/grants-approved.html b/email-templates/src/templates/grants-approved.html index a69142fa2c..890e8d5e9f 100644 --- a/email-templates/src/templates/grants-approved.html +++ b/email-templates/src/templates/grants-approved.html @@ -34,7 +34,8 @@ (includes AM and PM coffee breaks and Lunch for every conference day). - @{{#if hasApprovedTravel}} + @ + {{#if hasApprovedTravel}}
- To confirm your grant, - please click on the link below within the next 14 days (deadline - @{{ deadlineDateTime }}). If - for some reason you no longer need the grant, or you have any - questions or need more information please let us know by clicking - the link below. -
- -- Use the button above or click the link here: - @{{ replyLink }} -
-- Please note: - If we don't hear from you before - @{{ deadlineDate }}, we will - allocate your grant to another person. This is a firm deadline, - and your prompt response is necessary. -
-- If you require an invitation letter for a VISA, kindly - fill out our Visa Application Form. We will process your request and send you the invitation - letter within 4 days of form submission. -
-
- There's no need for you to purchase a ticket.
- We will provide you with a personalized voucher via a separate email.
- This voucher will allow you to redeem your free ticket directly on our website.
-
- Please keep an eye on your inbox, as we will be sending the voucher closer to the conference date.
-
- All grants involving reimbursements will be reimbursed based on - approved receipts (plane/bus/train ticket) sent to us before the - conference. The reimbursement will be made by a bank transfer or - with PayPal after the conference. -
-- We are always looking for passionate individuals to join our - volunteer team at PyCon Italia. Whether you've already signed up - to volunteer or are considering it, we deeply appreciate your - interest in contributing to our conference's success. ๐ -
-- For those who have expressed interest in volunteering, here's a - glimpse of what you might be involved in as part of our dedicated - conference staff: -
-- Your contribution as a volunteer is invaluable in making PyCon - Italia a welcoming and smoothly run event. If you have any - questions or need more information, please don't hesitate to - reach out. More detailed information will follow as the - conference approaches. -
-- Please let us know your thoughts regarding this matter or if you - need more information! :) -
-We can't wait to see you at the conference!
+ + ++ Use the button above or click the link here: + @{{ replyLink }} +
++ Please note: + If we don't hear from you before + @{{ deadlineDate }}, we will + allocate your grant to another person. This is a firm deadline, + and your prompt response is necessary. +
++ If you require an invitation letter for a VISA, visit our + VISA page + and complete the Visa Information Request form. +
+
+ There's no need for you to purchase a ticket.
+ We will provide you with a personalized voucher via a separate email.
+ This voucher will allow you to redeem your free ticket directly on our website.
+
+
+ Please keep an eye on your inbox, as we will be sending the voucher closer to the conference date.
+
+ All grants involving reimbursements will be reimbursed based on + approved receipts (plane/bus/train ticket) sent to us before the + conference. The reimbursement will be made by a bank transfer or + with PayPal after the conference. +
++ We are always looking for passionate individuals to join our + volunteer team at PyCon Italia. Whether you've already signed up + to volunteer or are considering it, we deeply appreciate your + interest in contributing to our conference's success. ๐ +
++ For those who have expressed interest in volunteering, here's a + glimpse of what you might be involved in as part of our dedicated + conference staff: +
++ Your contribution as a volunteer is invaluable in making PyCon + Italia a welcoming and smoothly run event. If you have any + questions or need more information, please don't hesitate to + reach out. More detailed information will follow as the + conference approaches. +
++ Please let us know your thoughts regarding this matter or if you + need more information! :) +
+We can't wait to see you at the conference!
+ + +
-
|
+