Skip to content

Commit 80a4231

Browse files
authored
Add BE Support for asking to not record a talk (#4509)
1 parent 10e42ac commit 80a4231

File tree

9 files changed

+134
-7
lines changed

9 files changed

+134
-7
lines changed

backend/api/submissions/mutations.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ class SendSubmissionInput(BaseSubmissionInput):
227227

228228
topic: Optional[ID] = strawberry.field(default=None)
229229
tags: list[ID] = strawberry.field(default_factory=list)
230+
do_not_record: bool = strawberry.field(default=False)
230231

231232

232233
@strawberry.input
@@ -257,6 +258,7 @@ class UpdateSubmissionInput(BaseSubmissionInput):
257258
topic: Optional[ID] = strawberry.field(default=None)
258259
tags: list[ID] = strawberry.field(default_factory=list)
259260
materials: list[SubmissionMaterialInput] = strawberry.field(default_factory=list)
261+
do_not_record: bool = strawberry.field(default=False)
260262

261263
def validate(self, conference: Conference, submission: SubmissionModel):
262264
errors = super().validate(conference)
@@ -319,6 +321,7 @@ def update_submission(
319321
instance.speaker_level = input.speaker_level
320322
instance.previous_talk_video = input.previous_talk_video
321323
instance.short_social_summary = input.short_social_summary
324+
instance.do_not_record = input.do_not_record
322325

323326
languages = Language.objects.filter(code__in=input.languages).all()
324327
instance.languages.set(languages)
@@ -437,6 +440,7 @@ def send_submission(
437440
notes=input.notes,
438441
audience_level_id=input.audience_level,
439442
short_social_summary=input.short_social_summary,
443+
do_not_record=input.do_not_record,
440444
)
441445

442446
languages = Language.objects.filter(code__in=input.languages).all()

backend/api/submissions/tests/test_edit_submission.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def _update_submission(
4646
new_speaker_mastodon_handle="",
4747
new_speaker_availabilities=None,
4848
new_materials=None,
49+
new_do_not_record=None,
4950
):
5051
new_topic = new_topic or submission.topic
5152
new_audience = new_audience or submission.audience_level
@@ -59,6 +60,7 @@ def _update_submission(
5960
new_speaker_photo = new_speaker_photo or FileFactory().id
6061
new_speaker_availabilities = new_speaker_availabilities or {}
6162
new_materials = new_materials or []
63+
new_do_not_record = new_do_not_record or submission.do_not_record
6264

6365
return graphql_client.query(
6466
"""
@@ -110,6 +112,7 @@ def _update_submission(
110112
111113
speakerLevel
112114
previousTalkVideo
115+
doNotRecord
113116
}
114117
115118
... on SendSubmissionErrors {
@@ -168,6 +171,7 @@ def _update_submission(
168171
"speakerMastodonHandle": new_speaker_mastodon_handle,
169172
"speakerAvailabilities": new_speaker_availabilities,
170173
"materials": new_materials,
174+
"doNotRecord": new_do_not_record,
171175
}
172176
},
173177
)
@@ -1256,3 +1260,44 @@ def test_edit_submission_multi_lingual_fields_required(graphql_client, user):
12561260
]
12571261

12581262
assert submission.languages.count() == 1
1263+
1264+
1265+
def test_update_submission_with_do_not_record_true(graphql_client, user):
1266+
graphql_client.force_login(user)
1267+
1268+
conference = ConferenceFactory(
1269+
topics=("life", "diy"),
1270+
languages=("it", "en"),
1271+
durations=("10", "20"),
1272+
active_cfp=True,
1273+
audience_levels=("adult", "senior"),
1274+
submission_types=("talk", "workshop"),
1275+
)
1276+
1277+
submission = SubmissionFactory(
1278+
speaker_id=user.id,
1279+
custom_topic="life",
1280+
custom_duration="10m",
1281+
custom_audience_level="adult",
1282+
custom_submission_type="talk",
1283+
languages=["it"],
1284+
tags=["python", "ml"],
1285+
conference=conference,
1286+
speaker_level=Submission.SPEAKER_LEVELS.intermediate,
1287+
previous_talk_video="https://www.youtube.com/watch?v=SlPhMPnQ58k",
1288+
do_not_record=False,
1289+
)
1290+
1291+
graphql_client.force_login(user)
1292+
1293+
response = _update_submission(
1294+
graphql_client,
1295+
submission=submission,
1296+
new_do_not_record=True,
1297+
)
1298+
1299+
assert response["data"]["updateSubmission"]["__typename"] == "Submission"
1300+
assert response["data"]["updateSubmission"]["doNotRecord"] is True
1301+
1302+
submission.refresh_from_db()
1303+
assert submission.do_not_record is True

backend/api/submissions/tests/test_send_submission.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def _submit_proposal(client, conference, submission, **kwargs):
104104
tags {
105105
name
106106
}
107+
doNotRecord
107108
}
108109
109110
... on SendSubmissionErrors {
@@ -207,6 +208,7 @@ def test_submit_talk(
207208
assert talk.speaker_id == user.id
208209
assert talk.audience_level.name == "Beginner"
209210
assert talk.short_social_summary == "summary"
211+
assert talk.do_not_record is False
210212

211213
participant = Participant.objects.get(conference=conference, user_id=user.id)
212214
assert participant.bio == "my bio"
@@ -1271,3 +1273,29 @@ def test_cannot_submit_more_than_3_proposals(graphql_client, user):
12711273
assert resp["data"]["sendSubmission"]["errors"]["nonFieldErrors"] == [
12721274
"You can only submit up to 3 proposals"
12731275
]
1276+
1277+
1278+
def test_submit_talk_with_do_not_record_true(graphql_client, user):
1279+
graphql_client.force_login(user)
1280+
1281+
conference = ConferenceFactory(
1282+
topics=("my-topic",),
1283+
languages=("en", "it"),
1284+
submission_types=("talk",),
1285+
active_cfp=True,
1286+
durations=("50",),
1287+
audience_levels=("Beginner",),
1288+
)
1289+
1290+
EmailTemplateFactory(
1291+
conference=conference,
1292+
identifier=EmailTemplateIdentifier.proposal_received_confirmation,
1293+
)
1294+
1295+
resp, _ = _submit_talk(graphql_client, conference, doNotRecord=True)
1296+
1297+
assert resp["data"]["sendSubmission"]["__typename"] == "Submission"
1298+
assert resp["data"]["sendSubmission"]["doNotRecord"] is True
1299+
1300+
talk = Submission.objects.get_by_hashid(resp["data"]["sendSubmission"]["id"])
1301+
assert talk.do_not_record is True

backend/api/submissions/tests/test_submissions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111

1212
def test_submissions_are_random_by_user(graphql_client, mock_has_ticket):
13-
user_1 = UserFactory(id=100)
14-
user_2 = UserFactory(id=103)
15-
user_3 = UserFactory(id=104)
13+
user_1 = UserFactory()
14+
user_2 = UserFactory()
15+
user_3 = UserFactory()
1616

1717
graphql_client.force_login(user_1)
1818

backend/api/submissions/types.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def resolver(self, info: Info):
3939
class SubmissionType:
4040
id: strawberry.ID
4141
name: str
42+
is_recordable: bool
4243

4344

4445
@strawberry.type
@@ -114,10 +115,11 @@ class Submission:
114115
topic: Annotated["Topic", strawberry.lazy("api.conferences.types")] | None
115116
type: SubmissionType | None
116117
duration: Annotated["Duration", strawberry.lazy("api.conferences.types")] | None
117-
audience_level: Annotated[
118-
"AudienceLevel", strawberry.lazy("api.conferences.types")
119-
] | None
118+
audience_level: (
119+
Annotated["AudienceLevel", strawberry.lazy("api.conferences.types")] | None
120+
)
120121
notes: str | None = private_field()
122+
do_not_record: bool | None = private_field()
121123

122124
@strawberry.field
123125
def schedule_items(

backend/submissions/admin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ class SubmissionAdmin(ExportMixin, ConferencePermissionMixin, admin.ModelAdmin):
249249
"conference",
250250
"audience_level",
251251
"languages",
252+
"do_not_record",
252253
)
253254
},
254255
),
@@ -325,7 +326,7 @@ class Media:
325326

326327
@admin.register(SubmissionType)
327328
class SubmissionTypeAdmin(admin.ModelAdmin):
328-
list_display = ("name",)
329+
list_display = ("name", "is_recordable")
329330

330331

331332
@admin.register(SubmissionTag)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.2.8 on 2025-12-14 13:25
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('submissions', '0028_alter_submission_pending_status'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='submission',
15+
name='do_not_record',
16+
field=models.BooleanField(default=False, help_text='If true, the submission will not be recorded.', verbose_name='do not record'),
17+
),
18+
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.2.8 on 2025-12-14 14:29
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('submissions', '0029_submission_do_not_record'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='submissiontype',
15+
name='is_recordable',
16+
field=models.BooleanField(default=True, help_text='If true, the proposals of this type can be recorded.', verbose_name='is recordable'),
17+
),
18+
]

backend/submissions/models.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ class Submission(TimeStampedModel):
107107
_("pending status"), choices=STATUS, max_length=20, null=True, blank=True
108108
)
109109

110+
do_not_record = models.BooleanField(
111+
_("do not record"),
112+
default=False,
113+
help_text=_("If true, the submission will not be recorded."),
114+
)
115+
110116
objects = SubmissionQuerySet().as_manager()
111117

112118
@property
@@ -230,6 +236,11 @@ def __str__(self):
230236

231237
class SubmissionType(models.Model):
232238
name = models.CharField(max_length=100, unique=True)
239+
is_recordable = models.BooleanField(
240+
_("is recordable"),
241+
default=True,
242+
help_text=_("If true, the proposals of this type can be recorded."),
243+
)
233244

234245
def __str__(self):
235246
return self.name

0 commit comments

Comments
 (0)