source: uri/tests/test_validators.py@ 262

Last change on this file since 262 was 230, checked in by wouter, 4 years ago

#91 clone https://pypi.org/project/rfc3986/

File size: 9.9 KB
Line 
1# -*- coding: utf-8 -*-
2"""Tests for the validators module."""
3import rfc3986
4from rfc3986 import exceptions
5from rfc3986 import validators
6
7import pytest
8
9
10def test_defaults():
11 """Verify the default Validator settings."""
12 validator = validators.Validator()
13
14 assert validator.required_components == {
15 c: False for c in validator.COMPONENT_NAMES
16 }
17 assert validator.allow_password is True
18 assert validator.allowed_schemes == set()
19 assert validator.allowed_hosts == set()
20 assert validator.allowed_ports == set()
21
22
23def test_allowing_schemes():
24 """Verify the ability to select schemes to be allowed."""
25 validator = validators.Validator().allow_schemes("http", "https")
26
27 assert "http" in validator.allowed_schemes
28 assert "https" in validator.allowed_schemes
29
30
31def test_allowing_hosts():
32 """Verify the ability to select hosts to be allowed."""
33 validator = validators.Validator().allow_hosts(
34 "pypi.python.org",
35 "pypi.org",
36 )
37
38 assert "pypi.python.org" in validator.allowed_hosts
39 assert "pypi.org" in validator.allowed_hosts
40
41
42def test_allowing_ports():
43 """Verify the ability select ports to be allowed."""
44 validator = validators.Validator().allow_ports("80", "100")
45
46 assert "80" in validator.allowed_ports
47 assert "100" in validator.allowed_ports
48
49
50def test_requiring_invalid_component():
51 """Verify that we validate required component names."""
52 with pytest.raises(ValueError):
53 validators.Validator().require_presence_of("frob")
54
55
56def test_checking_validity_of_component():
57 """Verify that we validate components we're validating."""
58 with pytest.raises(ValueError):
59 validators.Validator().check_validity_of("frob")
60
61
62def test_use_of_password():
63 """Verify the behaviour of {forbid,allow}_use_of_password."""
64 validator = validators.Validator()
65 assert validator.allow_password is True
66
67 validator.forbid_use_of_password()
68 assert validator.allow_password is False
69
70 validator.allow_use_of_password()
71 assert validator.allow_password is True
72
73
74@pytest.mark.parametrize(
75 "uri",
76 [
77 rfc3986.uri_reference("https://user:password@github.com"),
78 rfc3986.uri_reference("https://user:password@github.com/path"),
79 rfc3986.uri_reference("https://user:password@github.com/path?query"),
80 rfc3986.uri_reference(
81 "https://user:password@github.com/path?query#frag"
82 ),
83 rfc3986.uri_reference("//user:password@github.com"),
84 ],
85)
86def test_forbidden_passwords(uri):
87 """Verify that passwords are disallowed."""
88 validator = validators.Validator().forbid_use_of_password()
89 with pytest.raises(exceptions.PasswordForbidden):
90 validator.validate(uri)
91
92
93@pytest.mark.parametrize(
94 "uri",
95 [
96 rfc3986.uri_reference("https://user@github.com"),
97 rfc3986.uri_reference("https://user@github.com/path"),
98 rfc3986.uri_reference("https://user@github.com/path?query"),
99 rfc3986.uri_reference("https://user@github.com/path?query#frag"),
100 rfc3986.uri_reference("//user@github.com"),
101 rfc3986.uri_reference("//github.com"),
102 rfc3986.uri_reference("https://github.com"),
103 ],
104)
105def test_passwordless_uris_pass_validation(uri):
106 """Verify password-less URLs validate properly."""
107 validator = validators.Validator().forbid_use_of_password()
108 validator.validate(uri)
109
110
111@pytest.mark.parametrize(
112 "uri",
113 [
114 rfc3986.uri_reference("https://"),
115 rfc3986.uri_reference("/path/to/resource"),
116 ],
117)
118def test_missing_host_component(uri):
119 """Verify that missing host components cause errors."""
120 validators.Validator().validate(uri)
121
122 validator = validators.Validator().require_presence_of("host")
123 with pytest.raises(exceptions.MissingComponentError):
124 validator.validate(uri)
125
126
127@pytest.mark.parametrize(
128 "uri",
129 [
130 rfc3986.uri_reference("https://"),
131 rfc3986.uri_reference("//google.com"),
132 rfc3986.uri_reference("//google.com?query=value"),
133 rfc3986.uri_reference("//google.com#fragment"),
134 rfc3986.uri_reference("https://google.com"),
135 rfc3986.uri_reference("https://google.com#fragment"),
136 rfc3986.uri_reference("https://google.com?query=value"),
137 ],
138)
139def test_missing_path_component(uri):
140 """Verify that missing path components cause errors."""
141 validator = validators.Validator().require_presence_of("path")
142 with pytest.raises(exceptions.MissingComponentError):
143 validator.validate(uri)
144
145
146@pytest.mark.parametrize(
147 "uri",
148 [
149 rfc3986.uri_reference("//google.com"),
150 rfc3986.uri_reference("//google.com?query=value"),
151 rfc3986.uri_reference("//google.com#fragment"),
152 ],
153)
154def test_multiple_missing_components(uri):
155 """Verify that multiple missing components are caught."""
156 validator = validators.Validator().require_presence_of("scheme", "path")
157 with pytest.raises(exceptions.MissingComponentError) as captured_exc:
158 validator.validate(uri)
159 exception = captured_exc.value
160 assert 2 == len(exception.args[-1])
161
162
163@pytest.mark.parametrize(
164 "uri",
165 [
166 rfc3986.uri_reference("smtp://"),
167 rfc3986.uri_reference("telnet://"),
168 ],
169)
170def test_ensure_uri_has_a_scheme(uri):
171 """Verify validation with allowed schemes."""
172 validator = validators.Validator().allow_schemes("https", "http")
173 with pytest.raises(exceptions.UnpermittedComponentError):
174 validator.validate(uri)
175
176
177@pytest.mark.parametrize(
178 "uri, failed_component",
179 [
180 (rfc3986.uri_reference("git://github.com"), "scheme"),
181 (rfc3986.uri_reference("http://github.com"), "scheme"),
182 (rfc3986.uri_reference("ssh://gitlab.com"), "host"),
183 (rfc3986.uri_reference("https://gitlab.com"), "host"),
184 ],
185)
186def test_allowed_hosts_and_schemes(uri, failed_component):
187 """Verify each of these fails."""
188 validator = (
189 validators.Validator()
190 .allow_schemes(
191 "https",
192 "ssh",
193 )
194 .allow_hosts(
195 "github.com",
196 "git.openstack.org",
197 )
198 )
199 with pytest.raises(exceptions.UnpermittedComponentError) as caught_exc:
200 validator.validate(uri)
201
202 exc = caught_exc.value
203 assert exc.component_name == failed_component
204
205
206@pytest.mark.parametrize(
207 "uri",
208 [
209 rfc3986.uri_reference("https://github.com/sigmavirus24"),
210 rfc3986.uri_reference("ssh://github.com/sigmavirus24"),
211 rfc3986.uri_reference("ssh://ssh@github.com:22/sigmavirus24"),
212 rfc3986.uri_reference("https://github.com:443/sigmavirus24"),
213 rfc3986.uri_reference("https://gitlab.com/sigmavirus24"),
214 rfc3986.uri_reference("ssh://gitlab.com/sigmavirus24"),
215 rfc3986.uri_reference("ssh://ssh@gitlab.com:22/sigmavirus24"),
216 rfc3986.uri_reference("https://gitlab.com:443/sigmavirus24"),
217 rfc3986.uri_reference("https://bitbucket.org/sigmavirus24"),
218 rfc3986.uri_reference("ssh://bitbucket.org/sigmavirus24"),
219 rfc3986.uri_reference("ssh://ssh@bitbucket.org:22/sigmavirus24"),
220 rfc3986.uri_reference("https://bitbucket.org:443/sigmavirus24"),
221 rfc3986.uri_reference("https://git.openstack.org/sigmavirus24"),
222 rfc3986.uri_reference("ssh://git.openstack.org/sigmavirus24"),
223 rfc3986.uri_reference("ssh://ssh@git.openstack.org:22/sigmavirus24"),
224 rfc3986.uri_reference("https://git.openstack.org:443/sigmavirus24"),
225 rfc3986.uri_reference(
226 "ssh://ssh@git.openstack.org:22/sigmavirus24?foo=bar#fragment"
227 ),
228 rfc3986.uri_reference(
229 "ssh://git.openstack.org:22/sigmavirus24?foo=bar#fragment"
230 ),
231 rfc3986.uri_reference("ssh://git.openstack.org:22/?foo=bar#fragment"),
232 rfc3986.uri_reference(
233 "ssh://git.openstack.org:22/sigmavirus24#fragment"
234 ),
235 rfc3986.uri_reference("ssh://git.openstack.org:22/#fragment"),
236 rfc3986.uri_reference("ssh://git.openstack.org:22/"),
237 rfc3986.uri_reference(
238 "ssh://ssh@git.openstack.org:22/?foo=bar#fragment"
239 ),
240 rfc3986.uri_reference(
241 "ssh://ssh@git.openstack.org:22/sigmavirus24#fragment"
242 ),
243 rfc3986.uri_reference("ssh://ssh@git.openstack.org:22/#fragment"),
244 rfc3986.uri_reference("ssh://ssh@git.openstack.org:22/"),
245 ],
246)
247def test_successful_complex_validation(uri):
248 """Verify we do not raise ValidationErrors for good URIs."""
249 validators.Validator().allow_schemes("https", "ssh",).allow_hosts(
250 "github.com",
251 "bitbucket.org",
252 "gitlab.com",
253 "git.openstack.org",
254 ).allow_ports("22", "443",).require_presence_of(
255 "scheme",
256 "host",
257 "path",
258 ).check_validity_of(
259 "scheme",
260 "userinfo",
261 "host",
262 "port",
263 "path",
264 "query",
265 "fragment",
266 ).validate(
267 uri
268 )
269
270
271def test_invalid_uri_generates_error(invalid_uri):
272 """Verify we catch invalid URIs."""
273 uri = rfc3986.uri_reference(invalid_uri)
274 with pytest.raises(exceptions.InvalidComponentsError):
275 validators.Validator().check_validity_of("host").validate(uri)
276
277
278def test_invalid_uri_with_invalid_path(invalid_uri):
279 """Verify we catch multiple invalid components."""
280 uri = rfc3986.uri_reference(invalid_uri)
281 uri = uri.copy_with(path="#foobar")
282 with pytest.raises(exceptions.InvalidComponentsError):
283 validators.Validator().check_validity_of(
284 "host",
285 "path",
286 ).validate(uri)
287
288
289def test_validating_rfc_4007_ipv6_zone_ids():
290 """Verify that RFC 4007 IPv6 Zone IDs are invalid
291 host/authority but after normalization are valid
292 """
293 uri = rfc3986.uri_reference("http://[::1%eth0]")
294 with pytest.raises(exceptions.InvalidComponentsError):
295 validators.Validator().check_validity_of("host").validate(uri)
296
297 uri = uri.normalize()
298 assert uri.host == "[::1%25eth0]"
299
300 validators.Validator().check_validity_of("host").validate(uri)
Note: See TracBrowser for help on using the repository browser.