1+ from uuid import uuid4
2+ from users .tests .factories import UserFactory
13from conferences .tests .factories import ConferenceFactory
2- from submissions .tests .factories import SubmissionFactory , SubmissionTagFactory
3- from files_upload .tests .factories import FileFactory
4+ from submissions .tests .factories import (
5+ ProposalMaterialFactory ,
6+ SubmissionFactory ,
7+ SubmissionTagFactory ,
8+ )
9+ from files_upload .tests .factories import (
10+ FileFactory ,
11+ ParticipantAvatarFileFactory ,
12+ ProposalMaterialFileFactory ,
13+ )
414from pytest import mark
515
616from participants .models import Participant
7- from submissions .models import Submission
17+ from submissions .models import ProposalMaterial , Submission
818
919pytestmark = mark .django_db
1020
@@ -13,11 +23,11 @@ def _update_submission(
1323 graphql_client ,
1424 * ,
1525 submission ,
16- new_topic ,
17- new_audience ,
18- new_type ,
19- new_tag ,
20- new_duration ,
26+ new_topic = None ,
27+ new_audience = None ,
28+ new_type = None ,
29+ new_tag = None ,
30+ new_duration = None ,
2131 new_title = None ,
2232 new_elevator_pitch = None ,
2333 new_abstract = None ,
@@ -34,13 +44,20 @@ def _update_submission(
3444 new_speaker_facebook_url = "" ,
3545 new_speaker_mastodon_handle = "" ,
3646 new_speaker_availabilities = None ,
47+ new_materials = None ,
3748):
49+ new_topic = new_topic or submission .topic
50+ new_audience = new_audience or submission .audience_level
51+ new_type = new_type or submission .type
52+ new_tag = new_tag or submission .tags .first ()
53+ new_duration = new_duration or submission .duration
3854 new_title = new_title or {"en" : "new title to use" }
3955 new_elevator_pitch = new_elevator_pitch or {"en" : "This is an elevator pitch" }
4056 new_abstract = new_abstract or {"en" : "abstract here" }
4157 short_social_summary = new_short_social_summary or ""
4258 new_speaker_photo = new_speaker_photo or FileFactory ().id
4359 new_speaker_availabilities = new_speaker_availabilities or {}
60+ new_materials = new_materials or []
4461
4562 return graphql_client .query (
4663 """
@@ -114,6 +131,11 @@ def _update_submission(
114131 validationSpeakerInstagramHandle: speakerInstagramHandle
115132 validationSpeakerLinkedinUrl: speakerLinkedinUrl
116133 validationSpeakerFacebookUrl: speakerFacebookUrl
134+ validationMaterials: materials {
135+ fileId
136+ url
137+ id
138+ }
117139 }
118140 }
119141 }
@@ -144,6 +166,7 @@ def _update_submission(
144166 "speakerFacebookUrl" : new_speaker_facebook_url ,
145167 "speakerMastodonHandle" : new_speaker_mastodon_handle ,
146168 "speakerAvailabilities" : new_speaker_availabilities ,
169+ "materials" : new_materials ,
147170 }
148171 },
149172 )
@@ -204,6 +227,222 @@ def test_update_submission(graphql_client, user):
204227 assert participant .linkedin_url == "http://linkedin.com/company/pythonpizza"
205228
206229
230+ def test_update_submission_with_materials (graphql_client , user ):
231+ conference = ConferenceFactory (
232+ topics = ("life" , "diy" ),
233+ languages = ("it" , "en" ),
234+ durations = ("10" , "20" ),
235+ active_cfp = True ,
236+ audience_levels = ("adult" , "senior" ),
237+ submission_types = ("talk" , "workshop" ),
238+ )
239+
240+ submission = SubmissionFactory (
241+ speaker_id = user .id ,
242+ custom_topic = "life" ,
243+ custom_duration = "10m" ,
244+ custom_audience_level = "adult" ,
245+ custom_submission_type = "talk" ,
246+ languages = ["it" ],
247+ tags = ["python" , "ml" ],
248+ conference = conference ,
249+ speaker_level = Submission .SPEAKER_LEVELS .intermediate ,
250+ previous_talk_video = "https://www.youtube.com/watch?v=SlPhMPnQ58k" ,
251+ )
252+
253+ graphql_client .force_login (user )
254+
255+ new_file = FileFactory ()
256+ response = _update_submission (
257+ graphql_client ,
258+ submission = submission ,
259+ new_materials = [
260+ {
261+ "fileId" : new_file .id ,
262+ "url" : "" ,
263+ "name" : "test.pdf" ,
264+ },
265+ {
266+ "fileId" : None ,
267+ "url" : "https://www.google.com" ,
268+ "name" : "https://www.google.com" ,
269+ },
270+ ],
271+ )
272+
273+ submission .refresh_from_db ()
274+ materials = submission .materials .order_by ("id" ).all ()
275+
276+ assert len (materials ) == 2
277+ assert materials [0 ].file_id == new_file .id
278+ assert materials [0 ].url == ""
279+ assert materials [0 ].name == "test.pdf"
280+
281+ assert materials [1 ].file_id is None
282+ assert materials [1 ].url == "https://www.google.com"
283+ assert materials [1 ].name == "https://www.google.com"
284+
285+ assert response ["data" ]["updateSubmission" ]["__typename" ] == "Submission"
286+
287+
288+ def test_update_submission_with_existing_materials (graphql_client , user ):
289+ conference = ConferenceFactory (
290+ topics = ("life" , "diy" ),
291+ languages = ("it" , "en" ),
292+ durations = ("10" , "20" ),
293+ active_cfp = True ,
294+ audience_levels = ("adult" , "senior" ),
295+ submission_types = ("talk" , "workshop" ),
296+ )
297+
298+ submission = SubmissionFactory (
299+ speaker_id = user .id ,
300+ custom_topic = "life" ,
301+ custom_duration = "10m" ,
302+ custom_audience_level = "adult" ,
303+ custom_submission_type = "talk" ,
304+ languages = ["it" ],
305+ tags = ["python" , "ml" ],
306+ conference = conference ,
307+ speaker_level = Submission .SPEAKER_LEVELS .intermediate ,
308+ previous_talk_video = "https://www.youtube.com/watch?v=SlPhMPnQ58k" ,
309+ )
310+ existing_material = ProposalMaterialFactory (proposal = submission , file = FileFactory ())
311+ to_delete_material = ProposalMaterialFactory (
312+ proposal = submission , file = FileFactory ()
313+ )
314+
315+ graphql_client .force_login (user )
316+
317+ new_file = FileFactory ()
318+ response = _update_submission (
319+ graphql_client ,
320+ submission = submission ,
321+ new_materials = [
322+ {
323+ "fileId" : new_file .id ,
324+ "url" : "" ,
325+ "name" : "test.pdf" ,
326+ },
327+ {
328+ "id" : existing_material .id ,
329+ "fileId" : None ,
330+ "url" : "https://www.google.com" ,
331+ "name" : "https://www.google.com" ,
332+ },
333+ ],
334+ )
335+
336+ submission .refresh_from_db ()
337+ materials = submission .materials .order_by ("id" ).all ()
338+
339+ assert len (materials ) == 2
340+
341+ existing_material .refresh_from_db ()
342+
343+ assert existing_material .file_id is None
344+ assert existing_material .url == "https://www.google.com"
345+ assert existing_material .name == "https://www.google.com"
346+
347+ assert response ["data" ]["updateSubmission" ]["__typename" ] == "Submission"
348+
349+ assert not ProposalMaterial .objects .filter (id = to_delete_material .id ).exists ()
350+
351+
352+ def test_update_submission_with_invalid_materials (graphql_client , user ):
353+ conference = ConferenceFactory (
354+ topics = ("life" , "diy" ),
355+ languages = ("it" , "en" ),
356+ durations = ("10" , "20" ),
357+ active_cfp = True ,
358+ audience_levels = ("adult" , "senior" ),
359+ submission_types = ("talk" , "workshop" ),
360+ )
361+
362+ submission = SubmissionFactory (
363+ speaker_id = user .id ,
364+ custom_topic = "life" ,
365+ custom_duration = "10m" ,
366+ custom_audience_level = "adult" ,
367+ custom_submission_type = "talk" ,
368+ languages = ["it" ],
369+ tags = ["python" , "ml" ],
370+ conference = conference ,
371+ speaker_level = Submission .SPEAKER_LEVELS .intermediate ,
372+ previous_talk_video = "https://www.youtube.com/watch?v=SlPhMPnQ58k" ,
373+ )
374+ other_submission_material = ProposalMaterialFactory (
375+ proposal = SubmissionFactory (conference = conference ),
376+ file = ProposalMaterialFileFactory (uploaded_by = user ),
377+ )
378+ to_delete_material = ProposalMaterialFactory (
379+ proposal = submission , file = ProposalMaterialFileFactory (uploaded_by = user )
380+ )
381+
382+ graphql_client .force_login (user )
383+
384+ response = _update_submission (
385+ graphql_client ,
386+ submission = submission ,
387+ new_materials = [
388+ {
389+ "fileId" : None ,
390+ "url" : "invalid-url" ,
391+ "name" : "test.pdf" ,
392+ },
393+ {
394+ "id" : other_submission_material .id ,
395+ "fileId" : None ,
396+ "url" : "https://www.google.com" ,
397+ "name" : "https://www.google.com" ,
398+ },
399+ {
400+ "id" : "invalid-id" ,
401+ "fileId" : None ,
402+ "url" : "https://www.google.com" ,
403+ "name" : "https://www.google.com" ,
404+ },
405+ {
406+ "fileId" : uuid4 (),
407+ "url" : "" ,
408+ "name" : "name" ,
409+ },
410+ {
411+ "fileId" : ProposalMaterialFileFactory (uploaded_by = UserFactory ()).id ,
412+ "url" : "" ,
413+ "name" : "name" ,
414+ },
415+ {
416+ "fileId" : ParticipantAvatarFileFactory (uploaded_by = user ).id ,
417+ "url" : "" ,
418+ "name" : "name" ,
419+ },
420+ ],
421+ )
422+
423+ assert response ["data" ]["updateSubmission" ]["__typename" ] == "SendSubmissionErrors"
424+ assert response ["data" ]["updateSubmission" ]["errors" ]["validationMaterials" ][0 ][
425+ "url"
426+ ] == ["Invalid URL" ]
427+ assert response ["data" ]["updateSubmission" ]["errors" ]["validationMaterials" ][1 ][
428+ "id"
429+ ] == ["Material not found" ]
430+ assert response ["data" ]["updateSubmission" ]["errors" ]["validationMaterials" ][2 ][
431+ "id"
432+ ] == ["Invalid material id" ]
433+ assert response ["data" ]["updateSubmission" ]["errors" ]["validationMaterials" ][3 ][
434+ "fileId"
435+ ] == ["File not found" ]
436+ assert response ["data" ]["updateSubmission" ]["errors" ]["validationMaterials" ][4 ][
437+ "fileId"
438+ ] == ["File not found" ]
439+ assert response ["data" ]["updateSubmission" ]["errors" ]["validationMaterials" ][5 ][
440+ "fileId"
441+ ] == ["File not found" ]
442+
443+ assert ProposalMaterial .objects .filter (id = to_delete_material .id ).exists ()
444+
445+
207446def test_update_submission_speaker_availabilities (graphql_client , user ):
208447 conference = ConferenceFactory (
209448 topics = ("life" , "diy" ),
0 commit comments