summaryrefslogtreecommitdiff
path: root/test/test_fields.py
blob: c9c5fb9e84d4d061b8db5781e4ae833798bfa4cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from typing import List, Optional, Union

import pytest

from urllib3.fields import (
    RequestField,
    format_header_param,
    format_header_param_html5,
    format_header_param_rfc2231,
    format_multipart_header_param,
    guess_content_type,
)


class TestRequestField:
    @pytest.mark.parametrize(
        "filename, content_types",
        [
            ("image.jpg", ["image/jpeg", "image/pjpeg"]),
            ("notsure", ["application/octet-stream"]),
            (None, ["application/octet-stream"]),
        ],
    )
    def test_guess_content_type(
        self, filename: Optional[str], content_types: List[str]
    ) -> None:
        assert guess_content_type(filename) in content_types

    def test_create(self) -> None:
        simple_field = RequestField("somename", "data")
        assert simple_field.render_headers() == "\r\n"
        filename_field = RequestField("somename", "data", filename="somefile.txt")
        assert filename_field.render_headers() == "\r\n"
        headers_field = RequestField(
            "somename", "data", headers={"Content-Length": "4"}
        )
        assert headers_field.render_headers() == "Content-Length: 4\r\n\r\n"

    def test_make_multipart(self) -> None:
        field = RequestField("somename", "data")
        field.make_multipart(content_type="image/jpg", content_location="/test")
        assert (
            field.render_headers()
            == 'Content-Disposition: form-data; name="somename"\r\n'
            "Content-Type: image/jpg\r\n"
            "Content-Location: /test\r\n"
            "\r\n"
        )

    def test_make_multipart_empty_filename(self) -> None:
        field = RequestField("somename", "data", "")
        field.make_multipart(content_type="application/octet-stream")
        assert (
            field.render_headers()
            == 'Content-Disposition: form-data; name="somename"; filename=""\r\n'
            "Content-Type: application/octet-stream\r\n"
            "\r\n"
        )

    def test_render_parts(self) -> None:
        field = RequestField("somename", "data")
        parts = field._render_parts({"name": "value", "filename": "value"})
        assert 'name="value"' in parts
        assert 'filename="value"' in parts
        parts = field._render_parts([("name", "value"), ("filename", "value")])
        assert parts == 'name="value"; filename="value"'

    @pytest.mark.parametrize(
        ("value", "expect"),
        [("näme", "filename*=utf-8''n%C3%A4me"), (b"name", 'filename="name"')],
    )
    def test_format_header_param_rfc2231_deprecated(
        self, value: Union[bytes, str], expect: str
    ) -> None:
        with pytest.deprecated_call(match=r"urllib3 v3\.0\.0"):
            param = format_header_param_rfc2231("filename", value)

        assert param == expect

    def test_format_header_param_html5_deprecated(self) -> None:
        with pytest.deprecated_call(match=r"urllib3 v3\.0\.0"):
            param2 = format_header_param_html5("filename", "name")

        with pytest.deprecated_call(match=r"urllib3 v3\.0\.0"):
            param1 = format_header_param("filename", "name")

        assert param1 == param2

    @pytest.mark.parametrize(
        ("value", "expect"),
        [
            ("name", "name"),
            ("näme", "näme"),
            (b"n\xc3\xa4me", "näme"),
            ("ski ⛷.txt", "ski ⛷.txt"),
            ("control \x1A\x1B\x1C", "control \x1A\x1B\x1C"),
            ("backslash \\", "backslash \\"),
            ("quotes '\"", "quotes '%22"),
            ("newline \n\r", "newline %0A%0D"),
        ],
    )
    def test_format_multipart_header_param(
        self, value: Union[bytes, str], expect: str
    ) -> None:
        param = format_multipart_header_param("filename", value)
        assert param == f'filename="{expect}"'

    def test_from_tuples(self) -> None:
        field = RequestField.from_tuples("file", ("スキー旅行.txt", "data"))
        cd = field.headers["Content-Disposition"]
        assert cd == 'form-data; name="file"; filename="スキー旅行.txt"'

    def test_from_tuples_rfc2231(self) -> None:
        with pytest.deprecated_call(match=r"urllib3 v3\.0\.0"):
            field = RequestField.from_tuples(
                "file", ("näme", "data"), header_formatter=format_header_param_rfc2231
            )

        cd = field.headers["Content-Disposition"]
        assert cd == "form-data; name=\"file\"; filename*=utf-8''n%C3%A4me"