@@ -208,6 +208,111 @@ def test_Client_delete_operation(crud_api):
208208 assert resp .data == b'{"name": "test"}'
209209
210210
211+ def test_Client_create_operation_with_files (crud_api ):
212+ """Check that create() sends multipart form data when files is provided."""
213+ files = {"file" : ("data.csv" , b"a,b,c\n 1,2,3" , "text/csv" )}
214+ resp = crud_api .create ("upload/endpoint" , data = None , files = files )
215+
216+ crud_api .manager .request .assert_called_with (
217+ "POST" ,
218+ "https://localhost/upload/endpoint" ,
219+ fields = files ,
220+ headers = request_headers ,
221+ )
222+ assert resp .data == b'{"name": "test"}'
223+
224+
225+ def test_Client_create_operation_with_files_two_tuple (crud_api ):
226+ """Check that create() accepts 2-tuple (filename, data) without MIME type."""
227+ files = {"file" : ("data.csv" , b"a,b,c\n 1,2,3" )}
228+ resp = crud_api .create ("upload/endpoint" , data = None , files = files )
229+
230+ crud_api .manager .request .assert_called_with (
231+ "POST" ,
232+ "https://localhost/upload/endpoint" ,
233+ fields = files ,
234+ headers = request_headers ,
235+ )
236+ assert resp .data == b'{"name": "test"}'
237+
238+
239+ def test_Client_create_operation_with_files_mixed_fields (crud_api ):
240+ """Check that files dict can mix plain form fields with file tuples."""
241+ files = {
242+ "description" : "uploaded file" ,
243+ "file" : ("data.csv" , b"a,b,c\n 1,2,3" , "text/csv" ),
244+ }
245+ resp = crud_api .create ("upload/endpoint" , data = None , files = files )
246+
247+ crud_api .manager .request .assert_called_with (
248+ "POST" ,
249+ "https://localhost/upload/endpoint" ,
250+ fields = files ,
251+ headers = request_headers ,
252+ )
253+ assert resp .data == b'{"name": "test"}'
254+
255+
256+ def test_Client_create_operation_files_takes_precedence (crud_api ):
257+ """Check that files takes precedence over data when both are provided."""
258+ files = {"file" : ("doc.pdf" , b"%PDF-content" , "application/pdf" )}
259+ sample = {"should" : "be ignored" }
260+ resp = crud_api .create ("upload/endpoint" , data = sample , files = files )
261+
262+ crud_api .manager .request .assert_called_with (
263+ "POST" ,
264+ "https://localhost/upload/endpoint" ,
265+ fields = files ,
266+ headers = request_headers ,
267+ )
268+ assert resp .data == b'{"name": "test"}'
269+
270+
271+ def test_Client_update_operation_with_files (crud_api ):
272+ """Check that update() sends multipart form data when files is provided."""
273+ files = {"file" : ("data.csv" , b"a,b,c\n 1,2,3" , "text/csv" )}
274+ resp = crud_api .update ("upload/endpoint" , data = None , files = files )
275+
276+ crud_api .manager .request .assert_called_with (
277+ "PATCH" ,
278+ "https://localhost/upload/endpoint" ,
279+ fields = files ,
280+ headers = request_headers ,
281+ )
282+ assert resp .data == b'{"name": "test"}'
283+
284+
285+ def test_Client_update_operation_files_takes_precedence (crud_api ):
286+ """Check that files takes precedence over data when both are provided."""
287+ files = {"file" : ("doc.pdf" , b"%PDF-content" , "application/pdf" )}
288+ sample = {"should" : "be ignored" }
289+ resp = crud_api .update ("upload/endpoint" , data = sample , files = files )
290+
291+ crud_api .manager .request .assert_called_with (
292+ "PATCH" ,
293+ "https://localhost/upload/endpoint" ,
294+ fields = files ,
295+ headers = request_headers ,
296+ )
297+ assert resp .data == b'{"name": "test"}'
298+
299+
300+ def test_Client_update_operation_with_files_and_replace (crud_api ):
301+ """Check that update() with files and replace=True uses PUT method."""
302+ files = {"file" : ("data.csv" , b"a,b,c\n 1,2,3" , "text/csv" )}
303+ resp = crud_api .update (
304+ "upload/endpoint" , data = None , files = files , replace = True
305+ )
306+
307+ crud_api .manager .request .assert_called_with (
308+ "PUT" ,
309+ "https://localhost/upload/endpoint" ,
310+ fields = files ,
311+ headers = request_headers ,
312+ )
313+ assert resp .data == b'{"name": "test"}'
314+
315+
211316def test_Client_process_resp_return_bytes ():
212317 """
213318 Check the response processing returns bytes for non-JSON content.
0 commit comments