1 | # -*- coding: utf-8 -*-
|
---|
2 | # Copyright (c) 2017 Ian Stapleton Cordasco
|
---|
3 | # Licensed under the Apache License, Version 2.0 (the "License");
|
---|
4 | # you may not use this file except in compliance with the License.
|
---|
5 | # You may obtain a copy of the License at
|
---|
6 | #
|
---|
7 | # http://www.apache.org/licenses/LICENSE-2.0
|
---|
8 | #
|
---|
9 | # Unless required by applicable law or agreed to in writing, software
|
---|
10 | # distributed under the License is distributed on an "AS IS" BASIS,
|
---|
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
---|
12 | # implied.
|
---|
13 | # See the License for the specific language governing permissions and
|
---|
14 | # limitations under the License.
|
---|
15 | """Module containing the tests for the URIBuilder object."""
|
---|
16 | try:
|
---|
17 | from urllib.parse import parse_qs
|
---|
18 | except ImportError:
|
---|
19 | from urlparse import parse_qs
|
---|
20 |
|
---|
21 | import pytest
|
---|
22 |
|
---|
23 | from rfc3986 import builder, uri_reference
|
---|
24 |
|
---|
25 |
|
---|
26 | def test_builder_default():
|
---|
27 | """Verify the default values."""
|
---|
28 | uribuilder = builder.URIBuilder()
|
---|
29 | assert uribuilder.scheme is None
|
---|
30 | assert uribuilder.userinfo is None
|
---|
31 | assert uribuilder.host is None
|
---|
32 | assert uribuilder.port is None
|
---|
33 | assert uribuilder.path is None
|
---|
34 | assert uribuilder.query is None
|
---|
35 | assert uribuilder.fragment is None
|
---|
36 |
|
---|
37 |
|
---|
38 | def test_from_uri_reference():
|
---|
39 | uri = uri_reference("http://foo.bar:1234/baz")
|
---|
40 | uribuilder = builder.URIBuilder().from_uri(uri)
|
---|
41 | assert uribuilder.scheme == "http"
|
---|
42 | assert uribuilder.userinfo is None
|
---|
43 | assert uribuilder.host == "foo.bar"
|
---|
44 | assert uribuilder.port == "1234"
|
---|
45 | assert uribuilder.path == "/baz"
|
---|
46 | assert uribuilder.query is None
|
---|
47 | assert uribuilder.fragment is None
|
---|
48 |
|
---|
49 |
|
---|
50 | def test_from_uri_string():
|
---|
51 | uribuilder = builder.URIBuilder().from_uri("https://bar.foo:4321/boom")
|
---|
52 | assert uribuilder.scheme == "https"
|
---|
53 | assert uribuilder.userinfo is None
|
---|
54 | assert uribuilder.host == "bar.foo"
|
---|
55 | assert uribuilder.port == "4321"
|
---|
56 | assert uribuilder.path == "/boom"
|
---|
57 | assert uribuilder.query is None
|
---|
58 | assert uribuilder.fragment is None
|
---|
59 |
|
---|
60 |
|
---|
61 | def test_repr():
|
---|
62 | """Verify our repr looks like our class."""
|
---|
63 | uribuilder = builder.URIBuilder()
|
---|
64 | assert repr(uribuilder).startswith("URIBuilder(scheme=None")
|
---|
65 |
|
---|
66 |
|
---|
67 | @pytest.mark.parametrize(
|
---|
68 | "scheme",
|
---|
69 | [
|
---|
70 | "https",
|
---|
71 | "hTTps",
|
---|
72 | "Https",
|
---|
73 | "HtTpS",
|
---|
74 | "HTTPS",
|
---|
75 | ],
|
---|
76 | )
|
---|
77 | def test_add_scheme(scheme):
|
---|
78 | """Verify schemes are normalized when added."""
|
---|
79 | uribuilder = builder.URIBuilder().add_scheme(scheme)
|
---|
80 | assert uribuilder.scheme == "https"
|
---|
81 |
|
---|
82 |
|
---|
83 | @pytest.mark.parametrize(
|
---|
84 | "username, password, userinfo",
|
---|
85 | [
|
---|
86 | ("user", "pass", "user:pass"),
|
---|
87 | ("user", None, "user"),
|
---|
88 | ("user@domain.com", "password", "user%40domain.com:password"),
|
---|
89 | ("user", "pass:word", "user:pass%3Aword"),
|
---|
90 | ],
|
---|
91 | )
|
---|
92 | def test_add_credentials(username, password, userinfo):
|
---|
93 | """Verify we normalize usernames and passwords."""
|
---|
94 | uribuilder = builder.URIBuilder().add_credentials(username, password)
|
---|
95 | assert uribuilder.userinfo == userinfo
|
---|
96 |
|
---|
97 |
|
---|
98 | def test_add_credentials_requires_username():
|
---|
99 | """Verify one needs a username to add credentials."""
|
---|
100 | with pytest.raises(ValueError):
|
---|
101 | builder.URIBuilder().add_credentials(None, None)
|
---|
102 |
|
---|
103 |
|
---|
104 | @pytest.mark.parametrize(
|
---|
105 | ["hostname", "expected_hostname"],
|
---|
106 | [
|
---|
107 | ("google.com", "google.com"),
|
---|
108 | ("GOOGLE.COM", "google.com"),
|
---|
109 | ("gOOgLe.COM", "google.com"),
|
---|
110 | ("goOgLE.com", "google.com"),
|
---|
111 | ("[::ff%etH0]", "[::ff%25etH0]"),
|
---|
112 | ("[::ff%25etH0]", "[::ff%25etH0]"),
|
---|
113 | ("[::FF%etH0]", "[::ff%25etH0]"),
|
---|
114 | ],
|
---|
115 | )
|
---|
116 | def test_add_host(hostname, expected_hostname):
|
---|
117 | """Verify we normalize hostnames in add_host."""
|
---|
118 | uribuilder = builder.URIBuilder().add_host(hostname)
|
---|
119 | assert uribuilder.host == expected_hostname
|
---|
120 |
|
---|
121 |
|
---|
122 | @pytest.mark.parametrize(
|
---|
123 | "port",
|
---|
124 | [
|
---|
125 | -100,
|
---|
126 | "-100",
|
---|
127 | -1,
|
---|
128 | "-1",
|
---|
129 | 65536,
|
---|
130 | "65536",
|
---|
131 | 1000000,
|
---|
132 | "1000000",
|
---|
133 | "",
|
---|
134 | "abc",
|
---|
135 | "0b10",
|
---|
136 | ],
|
---|
137 | )
|
---|
138 | def test_add_invalid_port(port):
|
---|
139 | """Verify we raise a ValueError for invalid ports."""
|
---|
140 | with pytest.raises(ValueError):
|
---|
141 | builder.URIBuilder().add_port(port)
|
---|
142 |
|
---|
143 |
|
---|
144 | @pytest.mark.parametrize(
|
---|
145 | "port, expected",
|
---|
146 | [
|
---|
147 | (0, "0"),
|
---|
148 | ("0", "0"),
|
---|
149 | (1, "1"),
|
---|
150 | ("1", "1"),
|
---|
151 | (22, "22"),
|
---|
152 | ("22", "22"),
|
---|
153 | (80, "80"),
|
---|
154 | ("80", "80"),
|
---|
155 | (443, "443"),
|
---|
156 | ("443", "443"),
|
---|
157 | (65535, "65535"),
|
---|
158 | ("65535", "65535"),
|
---|
159 | ],
|
---|
160 | )
|
---|
161 | def test_add_port(port, expected):
|
---|
162 | """Verify we normalize our port."""
|
---|
163 | uribuilder = builder.URIBuilder().add_port(port)
|
---|
164 | assert uribuilder.port == expected
|
---|
165 |
|
---|
166 |
|
---|
167 | @pytest.mark.parametrize(
|
---|
168 | "path",
|
---|
169 | [
|
---|
170 | "sigmavirus24/rfc3986",
|
---|
171 | "/sigmavirus24/rfc3986",
|
---|
172 | ],
|
---|
173 | )
|
---|
174 | def test_add_path(path):
|
---|
175 | """Verify we normalize our path value."""
|
---|
176 | uribuilder = builder.URIBuilder().add_path(path)
|
---|
177 | assert uribuilder.path == "/sigmavirus24/rfc3986"
|
---|
178 |
|
---|
179 |
|
---|
180 | @pytest.mark.parametrize(
|
---|
181 | "query_items, expected",
|
---|
182 | [
|
---|
183 | ({"a": "b c"}, "a=b+c"),
|
---|
184 | ({"a": "b+c"}, "a=b%2Bc"),
|
---|
185 | ([("a", "b c")], "a=b+c"),
|
---|
186 | ([("a", "b+c")], "a=b%2Bc"),
|
---|
187 | ([("a", "b"), ("c", "d")], "a=b&c=d"),
|
---|
188 | ([("a", "b"), ("username", "@d")], "a=b&username=%40d"),
|
---|
189 | ([("percent", "%")], "percent=%25"),
|
---|
190 | ],
|
---|
191 | )
|
---|
192 | def test_add_query_from(query_items, expected):
|
---|
193 | """Verify the behaviour of add_query_from."""
|
---|
194 | uribuilder = builder.URIBuilder().add_query_from(query_items)
|
---|
195 | assert uribuilder.query == expected
|
---|
196 |
|
---|
197 |
|
---|
198 | def test_add_query():
|
---|
199 | """Verify we do not modify the provided query string."""
|
---|
200 | uribuilder = builder.URIBuilder().add_query("username=@foo")
|
---|
201 | assert uribuilder.query == "username=@foo"
|
---|
202 |
|
---|
203 |
|
---|
204 | def test_add_fragment():
|
---|
205 | """Verify our handling of fragments."""
|
---|
206 | uribuilder = builder.URIBuilder().add_fragment("section-2.5.1")
|
---|
207 | assert uribuilder.fragment == "section-2.5.1"
|
---|
208 |
|
---|
209 |
|
---|
210 | @pytest.mark.parametrize(
|
---|
211 | "uri, extend_with, expected_path",
|
---|
212 | [
|
---|
213 | ("https://api.github.com", "/users", "/users"),
|
---|
214 | ("https://api.github.com", "/users/", "/users/"),
|
---|
215 | ("https://api.github.com", "users", "/users"),
|
---|
216 | ("https://api.github.com", "users/", "/users/"),
|
---|
217 | ("", "users/", "/users/"),
|
---|
218 | ("", "users", "/users"),
|
---|
219 | ("?foo=bar", "users", "/users"),
|
---|
220 | (
|
---|
221 | "https://api.github.com/users/",
|
---|
222 | "sigmavirus24",
|
---|
223 | "/users/sigmavirus24",
|
---|
224 | ),
|
---|
225 | (
|
---|
226 | "https://api.github.com/users",
|
---|
227 | "sigmavirus24",
|
---|
228 | "/users/sigmavirus24",
|
---|
229 | ),
|
---|
230 | (
|
---|
231 | "https://api.github.com/users",
|
---|
232 | "/sigmavirus24",
|
---|
233 | "/users/sigmavirus24",
|
---|
234 | ),
|
---|
235 | ],
|
---|
236 | )
|
---|
237 | def test_extend_path(uri, extend_with, expected_path):
|
---|
238 | """Verify the behaviour of extend_path."""
|
---|
239 | uribuilder = (
|
---|
240 | builder.URIBuilder()
|
---|
241 | .from_uri(uri_reference(uri))
|
---|
242 | .extend_path(extend_with)
|
---|
243 | )
|
---|
244 | assert uribuilder.path == expected_path
|
---|
245 |
|
---|
246 |
|
---|
247 | @pytest.mark.parametrize(
|
---|
248 | "uri, extend_with, expected_query",
|
---|
249 | [
|
---|
250 | (
|
---|
251 | "https://github.com",
|
---|
252 | [("a", "b c"), ("d", "e&f")],
|
---|
253 | {"a": ["b c"], "d": ["e&f"]},
|
---|
254 | ),
|
---|
255 | (
|
---|
256 | "https://github.com?a=0",
|
---|
257 | [("a", "b c"), ("d", "e&f")],
|
---|
258 | {"a": ["0", "b c"], "d": ["e&f"]},
|
---|
259 | ),
|
---|
260 | (
|
---|
261 | "https://github.com?a=0&e=f",
|
---|
262 | [("a", "b c"), ("d", "e&f")],
|
---|
263 | {"a": ["0", "b c"], "e": ["f"], "d": ["e&f"]},
|
---|
264 | ),
|
---|
265 | (
|
---|
266 | "https://github.com",
|
---|
267 | {"a": "b c", "d": "e&f"},
|
---|
268 | {"a": ["b c"], "d": ["e&f"]},
|
---|
269 | ),
|
---|
270 | (
|
---|
271 | "https://github.com?a=0",
|
---|
272 | {"a": "b c", "d": "e&f"},
|
---|
273 | {"a": ["0", "b c"], "d": ["e&f"]},
|
---|
274 | ),
|
---|
275 | (
|
---|
276 | "https://github.com?a=0&e=f",
|
---|
277 | {"a": "b c", "d": "e&f"},
|
---|
278 | {"a": ["0", "b c"], "e": ["f"], "d": ["e&f"]},
|
---|
279 | ),
|
---|
280 | ],
|
---|
281 | )
|
---|
282 | def test_extend_query_with(uri, extend_with, expected_query):
|
---|
283 | """Verify the behaviour of extend_query_with."""
|
---|
284 | uribuilder = (
|
---|
285 | builder.URIBuilder()
|
---|
286 | .from_uri(uri_reference(uri))
|
---|
287 | .extend_query_with(extend_with)
|
---|
288 | )
|
---|
289 | assert parse_qs(uribuilder.query) == expected_query
|
---|
290 |
|
---|
291 |
|
---|
292 | def test_finalize():
|
---|
293 | """Verify the whole thing."""
|
---|
294 | uri = (
|
---|
295 | builder.URIBuilder()
|
---|
296 | .add_scheme("https")
|
---|
297 | .add_credentials("sigmavirus24", "not-my-re@l-password")
|
---|
298 | .add_host("github.com")
|
---|
299 | .add_path("sigmavirus24/rfc3986")
|
---|
300 | .finalize()
|
---|
301 | .unsplit()
|
---|
302 | )
|
---|
303 | expected = (
|
---|
304 | "https://sigmavirus24:not-my-re%40l-password@github.com/"
|
---|
305 | "sigmavirus24/rfc3986"
|
---|
306 | )
|
---|
307 | assert expected == uri
|
---|
308 |
|
---|
309 |
|
---|
310 | def test_geturl():
|
---|
311 | """Verify the short-cut to the URL."""
|
---|
312 | uri = (
|
---|
313 | builder.URIBuilder()
|
---|
314 | .add_scheme("https")
|
---|
315 | .add_credentials("sigmavirus24", "not-my-re@l-password")
|
---|
316 | .add_host("github.com")
|
---|
317 | .add_path("sigmavirus24/rfc3986")
|
---|
318 | .geturl()
|
---|
319 | )
|
---|
320 | expected = (
|
---|
321 | "https://sigmavirus24:not-my-re%40l-password@github.com/"
|
---|
322 | "sigmavirus24/rfc3986"
|
---|
323 | )
|
---|
324 | assert expected == uri
|
---|