source: uri/tests/test_validators.py@ 1108

Last change on this file since 1108 was 264, checked in by wouter, 3 years ago

#94 fix URI test code

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