deb-python-rfc3986/tests/test_validators.py

197 lines
7.1 KiB
Python

# -*- coding: utf-8 -*-
"""Tests for the validators module."""
import rfc3986
from rfc3986 import exceptions
from rfc3986 import validators
import pytest
def test_defaults():
"""Verify the default Validator settings."""
validator = validators.Validator()
assert validator.required_components == {
c: False for c in validator.COMPONENT_NAMES
}
assert validator.allow_password is True
assert validator.allowed_schemes == set()
assert validator.allowed_hosts == set()
assert validator.allowed_ports == set()
def test_allowing_schemes():
"""Verify the ability to select schemes to be allowed."""
validator = validators.Validator().allow_schemes('http', 'https')
assert 'http' in validator.allowed_schemes
assert 'https' in validator.allowed_schemes
def test_allowing_hosts():
"""Verify the ability to select hosts to be allowed."""
validator = validators.Validator().allow_hosts(
'pypi.python.org', 'pypi.org',
)
assert 'pypi.python.org' in validator.allowed_hosts
assert 'pypi.org' in validator.allowed_hosts
def test_allowing_ports():
"""Verify the ability select ports to be allowed."""
validator = validators.Validator().allow_ports('80', '100')
assert '80' in validator.allowed_ports
assert '100' in validator.allowed_ports
def test_requiring_invalid_component():
"""Verify that we validate required component names."""
with pytest.raises(ValueError):
validators.Validator().require_presence_of('frob')
def test_use_of_password():
"""Verify the behaviour of {forbid,allow}_use_of_password."""
validator = validators.Validator()
assert validator.allow_password is True
validator.forbid_use_of_password()
assert validator.allow_password is False
validator.allow_use_of_password()
assert validator.allow_password is True
@pytest.mark.parametrize('uri', [
rfc3986.uri_reference('https://user:password@github.com'),
rfc3986.uri_reference('https://user:password@github.com/path'),
rfc3986.uri_reference('https://user:password@github.com/path?query'),
rfc3986.uri_reference('https://user:password@github.com/path?query#frag'),
rfc3986.uri_reference('//user:password@github.com'),
])
def test_forbidden_passwords(uri):
"""Verify that passwords are disallowed."""
validator = validators.Validator().forbid_use_of_password()
with pytest.raises(exceptions.PasswordForbidden):
validator.validate(uri)
@pytest.mark.parametrize('uri', [
rfc3986.uri_reference('https://user@github.com'),
rfc3986.uri_reference('https://user@github.com/path'),
rfc3986.uri_reference('https://user@github.com/path?query'),
rfc3986.uri_reference('https://user@github.com/path?query#frag'),
rfc3986.uri_reference('//user@github.com'),
rfc3986.uri_reference('//github.com'),
rfc3986.uri_reference('https://github.com'),
])
def test_passwordless_uris_pass_validation(uri):
"""Verify password-less URLs validate properly."""
validator = validators.Validator().forbid_use_of_password()
validator.validate(uri)
@pytest.mark.parametrize('uri', [
rfc3986.uri_reference('https://'),
rfc3986.uri_reference('/path/to/resource'),
])
def test_missing_host_component(uri):
"""Verify that missing host components cause errors."""
validator = validators.Validator().require_presence_of('host')
with pytest.raises(exceptions.MissingComponentError):
validator.validate(uri)
@pytest.mark.parametrize('uri', [
rfc3986.uri_reference('https://'),
rfc3986.uri_reference('//google.com'),
rfc3986.uri_reference('//google.com?query=value'),
rfc3986.uri_reference('//google.com#fragment'),
rfc3986.uri_reference('https://google.com'),
rfc3986.uri_reference('https://google.com#fragment'),
rfc3986.uri_reference('https://google.com?query=value'),
])
def test_missing_path_component(uri):
"""Verify that missing path components cause errors."""
validator = validators.Validator().require_presence_of('path')
with pytest.raises(exceptions.MissingComponentError):
validator.validate(uri)
@pytest.mark.parametrize('uri', [
rfc3986.uri_reference('//google.com'),
rfc3986.uri_reference('//google.com?query=value'),
rfc3986.uri_reference('//google.com#fragment'),
])
def test_multiple_missing_components(uri):
"""Verify that multiple missing components are caught."""
validator = validators.Validator().require_presence_of('scheme', 'path')
with pytest.raises(exceptions.MissingComponentError) as captured_exc:
validator.validate(uri)
exception = captured_exc.value
assert 2 == len(exception.args[-1])
@pytest.mark.parametrize('uri', [
rfc3986.uri_reference('smtp://'),
rfc3986.uri_reference('telnet://'),
])
def test_ensure_uri_has_a_scheme(uri):
"""Verify validation with allowed schemes."""
validator = validators.Validator().allow_schemes('https', 'http')
with pytest.raises(exceptions.UnpermittedComponentError):
validator.validate(uri)
@pytest.mark.parametrize('uri, failed_component', [
(rfc3986.uri_reference('git://github.com'), 'scheme'),
(rfc3986.uri_reference('http://github.com'), 'scheme'),
(rfc3986.uri_reference('ssh://gitlab.com'), 'host'),
(rfc3986.uri_reference('https://gitlab.com'), 'host'),
])
def test_allowed_hosts_and_schemes(uri, failed_component):
"""Verify each of these fails."""
validator = validators.Validator().allow_schemes(
'https', 'ssh',
).allow_hosts(
'github.com', 'git.openstack.org',
)
with pytest.raises(exceptions.UnpermittedComponentError) as caught_exc:
validator.validate(uri)
exc = caught_exc.value
assert exc.component_name == failed_component
@pytest.mark.parametrize('uri', [
rfc3986.uri_reference('https://github.com/sigmavirus24'),
rfc3986.uri_reference('ssh://github.com/sigmavirus24'),
rfc3986.uri_reference('ssh://ssh@github.com:22/sigmavirus24'),
rfc3986.uri_reference('https://github.com:443/sigmavirus24'),
rfc3986.uri_reference('https://gitlab.com/sigmavirus24'),
rfc3986.uri_reference('ssh://gitlab.com/sigmavirus24'),
rfc3986.uri_reference('ssh://ssh@gitlab.com:22/sigmavirus24'),
rfc3986.uri_reference('https://gitlab.com:443/sigmavirus24'),
rfc3986.uri_reference('https://bitbucket.org/sigmavirus24'),
rfc3986.uri_reference('ssh://bitbucket.org/sigmavirus24'),
rfc3986.uri_reference('ssh://ssh@bitbucket.org:22/sigmavirus24'),
rfc3986.uri_reference('https://bitbucket.org:443/sigmavirus24'),
rfc3986.uri_reference('https://git.openstack.org/sigmavirus24'),
rfc3986.uri_reference('ssh://git.openstack.org/sigmavirus24'),
rfc3986.uri_reference('ssh://ssh@git.openstack.org:22/sigmavirus24'),
rfc3986.uri_reference('https://git.openstack.org:443/sigmavirus24'),
])
def test_successful_complex_validation(uri):
"""Verify we do not raise ValidationErrors for good URIs."""
validators.Validator().allow_schemes(
'https', 'ssh',
).allow_hosts(
'github.com', 'bitbucket.org', 'gitlab.com', 'git.openstack.org',
).allow_ports(
'22', '443',
).require_presence_of(
'scheme', 'host', 'path',
).validate(uri)