|
4 | 4 | from pathlib import Path
|
5 | 5 | from tempfile import gettempdir
|
6 | 6 | from unittest import mock
|
7 |
| -from unittest.mock import patch |
| 7 | +from unittest.mock import MagicMock, patch |
8 | 8 |
|
9 | 9 | import aiohttp
|
10 | 10 | import pytest
|
11 |
| -from aiohttp import ClientTimeout |
| 11 | +from aiohttp import ClientConnectorError, ClientTimeout |
| 12 | +from pytest_socket import SocketConnectBlockedError |
12 | 13 |
|
13 | 14 | import parfive
|
14 | 15 | from parfive.config import SessionConfig
|
@@ -495,24 +496,80 @@ def test_proxy_passed_as_kwargs_to_get(tmpdir, url, proxy):
|
495 | 496 | ]
|
496 | 497 |
|
497 | 498 |
|
498 |
| -def test_done_callback(httpserver, tmpdir): |
499 |
| - tmpdir = str(tmpdir) |
| 499 | +def test_http_callback_success(httpserver, tmpdir): |
| 500 | + # Test callback on successful download |
500 | 501 | httpserver.serve_content(
|
501 | 502 | "SIMPLE = T", headers={"Content-Disposition": "attachment; filename=testfile.fits"}
|
502 | 503 | )
|
503 | 504 |
|
504 |
| - def done_callback(filepath, url, error): |
505 |
| - (Path(gettempdir()) / "callback.done").touch() |
| 505 | + cb = MagicMock() |
| 506 | + dl = Downloader(config=SessionConfig(done_callbacks=[cb])) |
| 507 | + dl.enqueue_file(httpserver.url, path=tmpdir, max_splits=None) |
506 | 508 |
|
507 |
| - dl = Downloader(config=SessionConfig(done_callbacks=[done_callback])) |
508 |
| - dl.enqueue_file(httpserver.url, path=Path(tmpdir), max_splits=None) |
| 509 | + assert dl.queued_downloads == 1 |
| 510 | + |
| 511 | + dl.download() |
| 512 | + |
| 513 | + assert cb.call_count == 1 |
| 514 | + cb_path, cb_url, cb_status = cb.call_args[0] |
| 515 | + assert cb_path == tmpdir / "testfile.fits" |
| 516 | + assert httpserver.url == cb_url |
| 517 | + assert cb_status is None |
| 518 | + |
| 519 | + |
| 520 | +def test_http_callback_fail(httpserver, tmpdir): |
| 521 | + # Test callback on failed download |
| 522 | + cb = MagicMock() |
| 523 | + dl = Downloader(config=SessionConfig(done_callbacks=[cb])) |
| 524 | + url = "http://test.com/myfile.txt" |
| 525 | + dl.enqueue_file(url, path=tmpdir, max_splits=None) |
| 526 | + |
| 527 | + assert dl.queued_downloads == 1 |
| 528 | + |
| 529 | + dl.download() |
| 530 | + |
| 531 | + assert cb.call_count == 1 |
| 532 | + cb_path, cb_url, cb_status = cb.call_args[0] |
| 533 | + assert cb_path is None |
| 534 | + assert url == cb_url |
| 535 | + assert isinstance(cb_status, (SocketConnectBlockedError, ClientConnectorError)) |
| 536 | + |
| 537 | + |
| 538 | +@pytest.mark.allow_hosts(True) |
| 539 | +def test_ftp_callback_success(tmpdir): |
| 540 | + cb = MagicMock() |
| 541 | + dl = Downloader(config=SessionConfig(done_callbacks=[cb])) |
| 542 | + url = "ftp://ftp.swpc.noaa.gov/pub/warehouse/2011/2011_SRS.tar.gz" |
| 543 | + dl.enqueue_file(url, path=str(tmpdir)) |
| 544 | + |
| 545 | + assert dl.queued_downloads == 1 |
| 546 | + |
| 547 | + dl.download() |
| 548 | + |
| 549 | + assert cb.call_count == 1 |
| 550 | + cb_path, cb_url, cb_status = cb.call_args[0] |
| 551 | + assert cb_path == tmpdir / "2011_SRS.tar.gz" |
| 552 | + assert url == cb_url |
| 553 | + assert cb_status is None |
| 554 | + |
| 555 | + |
| 556 | +@mock.patch("aioftp.Client.context", side_effect=ConnectionRefusedError()) |
| 557 | +def test_ftp_callback_error(tmpdir): |
| 558 | + # Download should fail as not marked with allowed hosts |
| 559 | + cb = MagicMock() |
| 560 | + dl = Downloader(config=SessionConfig(done_callbacks=[cb])) |
| 561 | + url = "ftp://127.0.0.1/nosuchfile.txt" |
| 562 | + dl.enqueue_file(url, path=str(tmpdir)) |
509 | 563 |
|
510 | 564 | assert dl.queued_downloads == 1
|
511 | 565 |
|
512 | 566 | dl.download()
|
513 | 567 |
|
514 |
| - assert (Path(gettempdir()) / "callback.done").exists() |
515 |
| - (Path(gettempdir()) / "callback.done").unlink() |
| 568 | + assert cb.call_count == 1 |
| 569 | + cb_path, cb_url, cb_status = cb.call_args[0] |
| 570 | + assert cb_path is None |
| 571 | + assert cb_url == url |
| 572 | + assert isinstance(cb_status, ConnectionRefusedError) |
516 | 573 |
|
517 | 574 |
|
518 | 575 | class CustomThread(threading.Thread):
|
|
0 commit comments