pip/tests/unit/test_network_download.py

127 lines
3.3 KiB
Python

import logging
import sys
from typing import Dict
import pytest
from pip._internal.models.link import Link
from pip._internal.network.download import (
_prepare_download,
parse_content_disposition,
sanitize_content_filename,
)
from tests.lib.requests_mocks import MockResponse
@pytest.mark.parametrize(
"url, headers, from_cache, expected",
[
(
"http://example.com/foo.tgz",
{},
False,
"Downloading http://example.com/foo.tgz",
),
(
"http://example.com/foo.tgz",
{"content-length": "2"},
False,
"Downloading http://example.com/foo.tgz (2 bytes)",
),
(
"http://example.com/foo.tgz",
{"content-length": "2"},
True,
"Using cached http://example.com/foo.tgz (2 bytes)",
),
("https://files.pythonhosted.org/foo.tgz", {}, False, "Downloading foo.tgz"),
(
"https://files.pythonhosted.org/foo.tgz",
{"content-length": "2"},
False,
"Downloading foo.tgz (2 bytes)",
),
(
"https://files.pythonhosted.org/foo.tgz",
{"content-length": "2"},
True,
"Using cached foo.tgz",
),
],
)
def test_prepare_download__log(
caplog: pytest.LogCaptureFixture,
url: str,
headers: Dict[str, str],
from_cache: bool,
expected: str,
) -> None:
caplog.set_level(logging.INFO)
resp = MockResponse(b"")
resp.url = url
resp.headers = headers
if from_cache:
resp.from_cache = from_cache
link = Link(url)
_prepare_download(resp, link, progress_bar="on")
assert len(caplog.records) == 1
record = caplog.records[0]
assert record.levelname == "INFO"
assert expected in record.message
@pytest.mark.parametrize(
"filename, expected",
[
("dir/file", "file"),
("../file", "file"),
("../../file", "file"),
("../", ""),
("../..", ".."),
("/", ""),
],
)
def test_sanitize_content_filename(filename: str, expected: str) -> None:
"""
Test inputs where the result is the same for Windows and non-Windows.
"""
assert sanitize_content_filename(filename) == expected
@pytest.mark.parametrize(
"filename, win_expected, non_win_expected",
[
("dir\\file", "file", "dir\\file"),
("..\\file", "file", "..\\file"),
("..\\..\\file", "file", "..\\..\\file"),
("..\\", "", "..\\"),
("..\\..", "..", "..\\.."),
("\\", "", "\\"),
],
)
def test_sanitize_content_filename__platform_dependent(
filename: str, win_expected: str, non_win_expected: str
) -> None:
"""
Test inputs where the result is different for Windows and non-Windows.
"""
if sys.platform == "win32":
expected = win_expected
else:
expected = non_win_expected
assert sanitize_content_filename(filename) == expected
@pytest.mark.parametrize(
"content_disposition, default_filename, expected",
[
('attachment;filename="../file"', "df", "file"),
],
)
def test_parse_content_disposition(
content_disposition: str, default_filename: str, expected: str
) -> None:
actual = parse_content_disposition(content_disposition, default_filename)
assert actual == expected