11import json
2+ import random
23import uuid
34from collections import defaultdict
45
56import factory
67import wagtail_factories
8+ from django .core .files .base import File
79from django .core .files .uploadedfile import SimpleUploadedFile
810from django .core .serializers .json import DjangoJSONEncoder
911from wagtail .blocks import RichTextBlock , StructValue
@@ -73,6 +75,18 @@ def _create(cls, *args, form_fields=None, for_factory=None, clean=False, **kwarg
7375 or for_factory .Meta .model .form_fields .field .to_python (form_fields )
7476 }
7577
78+ # Get UUIDs of the file fields to add "-uploads" fields later
79+ file_fields = []
80+ file_types = ("image" , "file" , "multi_file" )
81+ for field in form_fields :
82+ try :
83+ if field ["type" ] in file_types :
84+ file_fields .append (field ["id" ])
85+ except TypeError :
86+ if field .block_type in file_types :
87+ file_fields .append (field .id )
88+ # field["id"] for field in form_fields if field["type"] in ("file", "multi_file")]
89+
7690 form_data = {}
7791 for name , answer in kwargs .items ():
7892 try :
@@ -92,6 +106,25 @@ def _create(cls, *args, form_fields=None, for_factory=None, clean=False, **kwarg
92106 clean_object .delete ()
93107 return form_data
94108
109+ for id in file_fields :
110+ uploads = []
111+ if entry := form_data .get (id ):
112+ if not isinstance (entry , list ):
113+ entry = [entry ]
114+
115+ for file in entry :
116+ uploads .append (
117+ {
118+ "id" : str (uuid .uuid4 ()),
119+ "name" : file ._name ,
120+ "size" : random .randint (20 , 100000 ),
121+ "type" : "tus" ,
122+ "url" : "" ,
123+ }
124+ )
125+
126+ form_data [f"{ id } -uploads" ] = json .dumps (uploads )
127+
95128 return form_data
96129
97130 @classmethod
@@ -242,6 +275,17 @@ def make_answer(cls, params=None):
242275 return cls .choices [0 ]
243276
244277
278+ class UploadedFile (SimpleUploadedFile ):
279+ """Utilized to make functionality closer to that of `StreamFieldFile`
280+
281+ Requires a `filename` attribute which is pulled from the existing `_name`
282+ """
283+
284+ def __init__ (self , name , content , content_type = ...):
285+ super ().__init__ (name , content , content_type )
286+ self .filename = self ._name
287+
288+
245289class UploadableMediaFactory (FormFieldBlockFactory ):
246290 default_value = factory .django .FileField ()
247291
@@ -252,7 +296,7 @@ def make_answer(cls, params=None):
252296 if params .get ("filename" ) is None :
253297 params ["filename" ] = "test_example.pdf"
254298 file_name , file = cls .default_value ._make_content (params )
255- return SimpleUploadedFile (file_name , file .read ())
299+ return UploadedFile (file_name , file .read ())
256300
257301
258302class ImageFieldBlockFactory (UploadableMediaFactory ):
@@ -276,6 +320,16 @@ def make_answer(cls, params=None):
276320 return [UploadableMediaFactory .make_answer () for _ in range (2 )]
277321
278322
323+ class StreamFieldDataEncoder (DjangoJSONEncoder ):
324+ def default (self , o ):
325+ if isinstance (o , File ):
326+ return {
327+ "name" : o .name ,
328+ "filename" : o .filename ,
329+ }
330+ return super ().default (o )
331+
332+
279333class StreamFieldUUIDFactory (wagtail_factories .StreamFieldFactory ):
280334 def evaluate (self , instance , step , extra ):
281335 params = self .build_form (extra )
0 commit comments