Skip to content

Commit 9e5053b

Browse files
committed
Send confirmation email when the user submits a proposal
1 parent 46c7657 commit 9e5053b

File tree

5 files changed

+101
-3
lines changed

5 files changed

+101
-3
lines changed

backend/api/submissions/mutations.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
from urllib.parse import urljoin
2+
from django.conf import settings
3+
from grants.tasks import get_name
4+
from notifications.models import EmailTemplate, EmailTemplateIdentifier
15
from strawberry.scalars import JSON
26

37
from django.db import transaction
@@ -383,6 +387,24 @@ def send_submission(
383387
"cfp",
384388
)
385389

390+
email_template = EmailTemplate.objects.for_conference(
391+
conference
392+
).get_by_identifier(EmailTemplateIdentifier.proposal_received_confirmation)
393+
394+
proposal_url = urljoin(
395+
settings.FRONTEND_URL,
396+
f"/submission/{instance.hashid}",
397+
)
398+
399+
email_template.send_email(
400+
recipient=request.user,
401+
placeholders={
402+
"user_name": get_name(request.user, "there"),
403+
"proposal_title": instance.title.localize("en"),
404+
"proposal_url": proposal_url,
405+
},
406+
)
407+
386408
def _notify_new_submission():
387409
notify_new_cfp_submission.delay(
388410
submission_id=instance.id,

backend/api/submissions/tests/test_send_submission.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from notifications.models import EmailTemplateIdentifier
2+
from notifications.tests.factories import EmailTemplateFactory
13
from privacy_policy.models import PrivacyPolicyAcceptanceRecord
24
from files_upload.tests.factories import FileFactory
35
from conferences.tests.factories import (
@@ -138,7 +140,11 @@ def _submit_proposal(client, conference, submission, **kwargs):
138140
)
139141

140142

141-
def test_submit_talk(graphql_client, user, django_capture_on_commit_callbacks, mocker):
143+
def test_submit_talk(
144+
graphql_client, user, django_capture_on_commit_callbacks, mocker, settings
145+
):
146+
settings.FRONTEND_URL = "http://testserver"
147+
mock_email_template = mocker.patch("api.submissions.mutations.EmailTemplate")
142148
mock_notify = mocker.patch("api.submissions.mutations.notify_new_cfp_submission")
143149
graphql_client.force_login(user)
144150

@@ -151,6 +157,11 @@ def test_submit_talk(graphql_client, user, django_capture_on_commit_callbacks, m
151157
audience_levels=("Beginner",),
152158
)
153159

160+
EmailTemplateFactory(
161+
conference=conference,
162+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
163+
)
164+
154165
speaker_photo = FileFactory().id
155166

156167
with django_capture_on_commit_callbacks(execute=True):
@@ -208,6 +219,15 @@ def test_submit_talk(graphql_client, user, django_capture_on_commit_callbacks, m
208219

209220
mock_notify.delay.assert_called_once()
210221

222+
mock_email_template.objects.for_conference().get_by_identifier().send_email.assert_called_once_with(
223+
recipient=user,
224+
placeholders={
225+
"user_name": user.full_name,
226+
"proposal_title": "English",
227+
"proposal_url": f"http://testserver/submission/{talk.hashid}",
228+
},
229+
)
230+
211231

212232
def test_submit_talk_with_photo_to_upload(graphql_client, user, mocker):
213233
graphql_client.force_login(user)
@@ -220,7 +240,10 @@ def test_submit_talk_with_photo_to_upload(graphql_client, user, mocker):
220240
durations=("50",),
221241
audience_levels=("Beginner",),
222242
)
223-
243+
EmailTemplateFactory(
244+
conference=conference,
245+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
246+
)
224247
speaker_photo = FileFactory().id
225248

226249
resp, variables = _submit_talk(
@@ -253,6 +276,11 @@ def test_submit_talk_without_photo_fails(graphql_client, user, mocker):
253276
audience_levels=("Beginner",),
254277
)
255278

279+
EmailTemplateFactory(
280+
conference=conference,
281+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
282+
)
283+
256284
resp, variables = _submit_talk(
257285
graphql_client,
258286
conference,
@@ -282,6 +310,11 @@ def test_submit_talk_with_existing_participant(graphql_client, user):
282310
audience_levels=("Beginner",),
283311
)
284312

313+
EmailTemplateFactory(
314+
conference=conference,
315+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
316+
)
317+
285318
participant = Participant.objects.create(
286319
conference=conference, user_id=user.id, bio="old bio"
287320
)
@@ -339,6 +372,11 @@ def test_submit_talk_with_missing_data_of_other_language_fails(graphql_client, u
339372
audience_levels=("Beginner",),
340373
)
341374

375+
EmailTemplateFactory(
376+
conference=conference,
377+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
378+
)
379+
342380
resp, _ = _submit_talk(
343381
graphql_client,
344382
conference,
@@ -370,6 +408,11 @@ def test_submit_talk_with_missing_data_fails(graphql_client, user):
370408
audience_levels=("Beginner",),
371409
)
372410

411+
EmailTemplateFactory(
412+
conference=conference,
413+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
414+
)
415+
373416
resp, _ = _submit_talk(
374417
graphql_client,
375418
conference,
@@ -413,6 +456,11 @@ def test_submit_talk_with_multiple_languages(graphql_client, user):
413456
audience_levels=("Beginner",),
414457
)
415458

459+
EmailTemplateFactory(
460+
conference=conference,
461+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
462+
)
463+
416464
resp, variables = _submit_talk(
417465
graphql_client,
418466
conference,

backend/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
@pytest.fixture()
2020
def user(db):
21-
return UserFactory(email="[email protected]", is_staff=False)
21+
return UserFactory(email="[email protected]", is_staff=False, full_name="Jane Doe")
2222

2323

2424
@pytest.fixture()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.1.1 on 2024-12-01 14:41
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('notifications', '0018_alter_emailtemplate_identifier'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='emailtemplate',
15+
name='identifier',
16+
field=models.CharField(choices=[('proposal_accepted', 'Proposal accepted'), ('proposal_rejected', 'Proposal rejected'), ('proposal_in_waiting_list', 'Proposal in waiting list'), ('proposal_scheduled_time_changed', 'Proposal scheduled time changed'), ('proposal_received_confirmation', 'Proposal received confirmation'), ('speaker_communication', 'Speaker communication'), ('voucher_code', 'Voucher code'), ('reset_password', '[System] Reset password'), ('grant_application_confirmation', 'Grant application confirmation'), ('grant_approved', 'Grant approved'), ('grant_rejected', 'Grant rejected'), ('grant_waiting_list', 'Grant waiting list'), ('grant_waiting_list_update', 'Grant waiting list update'), ('grant_voucher_code', 'Grant voucher code'), ('sponsorship_brochure', 'Sponsorship brochure'), ('custom', 'Custom')], max_length=200, verbose_name='identifier'),
17+
),
18+
]

backend/notifications/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class EmailTemplateIdentifier(models.TextChoices):
2323
"proposal_scheduled_time_changed",
2424
_("Proposal scheduled time changed"),
2525
)
26+
proposal_received_confirmation = (
27+
"proposal_received_confirmation",
28+
_("Proposal received confirmation"),
29+
)
2630
speaker_communication = "speaker_communication", _("Speaker communication")
2731

2832
voucher_code = "voucher_code", _("Voucher code")
@@ -88,6 +92,12 @@ class EmailTemplate(TimeStampedModel):
8892
*BASE_PLACEHOLDERS,
8993
"user_name",
9094
],
95+
EmailTemplateIdentifier.proposal_received_confirmation: [
96+
*BASE_PLACEHOLDERS,
97+
"user_name",
98+
"proposal_title",
99+
"proposal_url",
100+
],
91101
EmailTemplateIdentifier.grant_approved: [
92102
*BASE_PLACEHOLDERS,
93103
"reply_url",

0 commit comments

Comments
 (0)