@@ -276,3 +276,147 @@ def test_batch_download_rate_limit_429(
276276 assert mocked_batch_list_files .call_args .args == (job_id ,)
277277 assert len (downloaded_files ) == 1
278278 assert downloaded_files [0 ].read_bytes () == file_content
279+
280+
281+ def test_batch_download_file_exists (
282+ monkeypatch : pytest .MonkeyPatch ,
283+ historical_client : Historical ,
284+ tmp_path : Path ,
285+ ) -> None :
286+ """
287+ Tests batch download by setting up a MagicMock which will return the
288+ content "unittest".
289+
290+ A subsequent call to batch.download should not fail.
291+
292+ """
293+ # Arrange
294+ job_id = "GLBX-20220610-5DEFXVTMSM"
295+ filename = "glbx-mdp3-20220610.mbo.csv.zst"
296+ file_content = b"unittest"
297+ file_hash = f"sha256:{ hashlib .sha256 (file_content ).hexdigest ()} "
298+ file_size = len (file_content )
299+
300+ # Mock the call to list files so it returns a test manifest
301+ monkeypatch .setattr (
302+ historical_client .batch ,
303+ "list_files" ,
304+ mocked_batch_list_files := MagicMock (
305+ return_value = [
306+ {
307+ "filename" : filename ,
308+ "hash" : file_hash ,
309+ "size" : file_size ,
310+ "urls" : {
311+ "https" : f"localhost:442/v0/batch/download/TESTUSER/{ job_id } /{ filename } " ,
312+ "ftp" : "" ,
313+ },
314+ },
315+ ],
316+ ),
317+ )
318+
319+ # Mock the call for get, so we can simulate a 429 response
320+ ok_response = MagicMock ()
321+ ok_response .__enter__ .return_value = MagicMock (
322+ status_code = 200 ,
323+ iter_content = MagicMock (return_value = iter ([file_content ])),
324+ )
325+ monkeypatch .setattr (
326+ requests ,
327+ "get" ,
328+ MagicMock (
329+ side_effect = [ok_response ],
330+ ),
331+ )
332+
333+ # Act
334+ historical_client .batch .download (
335+ job_id = job_id ,
336+ output_dir = tmp_path ,
337+ filename_to_download = filename ,
338+ )
339+
340+ downloaded_files = historical_client .batch .download (
341+ job_id = job_id ,
342+ output_dir = tmp_path ,
343+ filename_to_download = filename ,
344+ )
345+
346+ # Assert
347+ assert mocked_batch_list_files .call_args .args == (job_id ,)
348+ assert len (downloaded_files ) == 1
349+ assert downloaded_files [0 ].read_bytes () == file_content
350+
351+
352+ def test_batch_download_file_larger_than_expected (
353+ monkeypatch : pytest .MonkeyPatch ,
354+ historical_client : Historical ,
355+ tmp_path : Path ,
356+ ) -> None :
357+ """
358+ Tests batch download by setting up a MagicMock which will return the
359+ content "unittest".
360+
361+ Then, write some extra bytes to that file, and ensure a subsequent
362+ call to batch.download will raise an exception.
363+
364+ """
365+ # Arrange
366+ job_id = "GLBX-20220610-5DEFXVTMSM"
367+ filename = "glbx-mdp3-20220610.mbo.csv.zst"
368+ file_content = b"unittest"
369+ file_hash = f"sha256:{ hashlib .sha256 (file_content ).hexdigest ()} "
370+ file_size = len (file_content )
371+
372+ # Mock the call to list files so it returns a test manifest
373+ monkeypatch .setattr (
374+ historical_client .batch ,
375+ "list_files" ,
376+ MagicMock (
377+ return_value = [
378+ {
379+ "filename" : filename ,
380+ "hash" : file_hash ,
381+ "size" : file_size ,
382+ "urls" : {
383+ "https" : f"localhost:442/v0/batch/download/TESTUSER/{ job_id } /{ filename } " ,
384+ "ftp" : "" ,
385+ },
386+ },
387+ ],
388+ ),
389+ )
390+
391+ # Mock the call for get, so we can simulate a 429 response
392+ ok_response = MagicMock ()
393+ ok_response .__enter__ .return_value = MagicMock (
394+ status_code = 200 ,
395+ iter_content = MagicMock (return_value = iter ([file_content ])),
396+ )
397+ monkeypatch .setattr (
398+ requests ,
399+ "get" ,
400+ MagicMock (
401+ side_effect = [ok_response ],
402+ ),
403+ )
404+
405+ # Act
406+ downloaded_files = historical_client .batch .download (
407+ job_id = job_id ,
408+ output_dir = tmp_path ,
409+ filename_to_download = filename ,
410+ )
411+
412+ # Increase the existing file size with some junk
413+ with downloaded_files [- 1 ].open (mode = "ab" ) as out :
414+ out .write (b"junk" )
415+
416+ # Assert
417+ with pytest .raises (FileExistsError ):
418+ historical_client .batch .download (
419+ job_id = job_id ,
420+ output_dir = tmp_path ,
421+ filename_to_download = filename ,
422+ )
0 commit comments