# -*- coding: utf-8 -*- import pytest from rfc3986.exceptions import InvalidAuthority from rfc3986.misc import URI_MATCHER from rfc3986.uri import URIReference valid_hosts = [ '[21DA:00D3:0000:2F3B:02AA:00FF:FE28:9C5A]', '[::1]', '[21DA:D3:0:2F3B:2AA:FF:FE28:9C5A]', '[FE80::2AA:FF:FE9A:4CA2]', '[FF02::2]', '[FF02:3::5]', '[FF02:0:0:0:0:0:0:2]', '[FF02:30:0:0:0:0:0:5]', '127.0.0.1', 'www.example.com', 'localhost' ] invalid_hosts = [ '[FF02::3::5]', # IPv6 can only have one :: '[FADF:01]', # Not properly compacted (missing a :) 'localhost:80:80:80' # Too many ports ] @pytest.fixture(params=valid_hosts) def basic_uri(request): return 'http://%s' % request.param @pytest.fixture(params=valid_hosts) def basic_uri_with_port(request): return 'ftp://%s:21' % request.param @pytest.fixture(params=valid_hosts) def uri_with_port_and_userinfo(request): return 'ssh://user:pass@%s:22' % request.param @pytest.fixture(params=valid_hosts) def basic_uri_with_path(request): return 'http://%s/path/to/resource' % request.param @pytest.fixture(params=valid_hosts) def uri_with_path_and_query(request): return 'http://%s/path/to/resource?key=value' % request.param @pytest.fixture(params=valid_hosts) def uri_with_everything(request): return 'https://user:pass@%s:443/path/to/resource?key=value#fragment' % ( request.param) @pytest.fixture(params=valid_hosts) def relative_uri(request): return '//%s' % request.param @pytest.fixture def absolute_path_uri(): return '/path/to/file' @pytest.fixture(params=invalid_hosts) def invalid_uri(request): return 'https://%s' % request.param @pytest.fixture def scheme_and_path_uri(): return 'mailto:user@example.com' class TestURIReferenceParsesURIs: """Tests for URIReference handling of URIs.""" def test_handles_basic_uri(self, basic_uri): """Test that URIReference can handle a simple URI.""" uri = URIReference.from_string(basic_uri) assert uri.scheme == 'http' assert uri.authority == basic_uri[7:] # len('http://') assert uri.host == uri.authority assert uri.path is None assert uri.query is None assert uri.fragment is None assert uri.port is None assert uri.userinfo is None def test_handles_basic_uri_with_port(self, basic_uri_with_port): """Test that URIReference can handle a simple URI with a port.""" uri = URIReference.from_string(basic_uri_with_port) assert uri.scheme == 'ftp' assert uri.authority == basic_uri_with_port[6:] # len('ftp://') assert uri.host != uri.authority assert uri.port == '21' assert uri.path is None assert uri.query is None assert uri.fragment is None assert uri.userinfo is None def test_handles_uri_with_port_and_userinfo( self, uri_with_port_and_userinfo): """ Test that URIReference can handle a URI with a port and userinfo. """ uri = URIReference.from_string(uri_with_port_and_userinfo) assert uri.scheme == 'ssh' # 6 == len('ftp://') assert uri.authority == uri_with_port_and_userinfo[6:] assert uri.host != uri.authority assert uri.port == '22' assert uri.path is None assert uri.query is None assert uri.fragment is None assert uri.userinfo == 'user:pass' def test_handles_basic_uri_with_path(self, basic_uri_with_path): """Test that URIReference can handle a URI with a path.""" uri = URIReference.from_string(basic_uri_with_path) assert uri.scheme == 'http' assert basic_uri_with_path == (uri.scheme + '://' + uri.authority + uri.path) assert uri.host == uri.authority assert uri.path == '/path/to/resource' assert uri.query is None assert uri.fragment is None assert uri.userinfo is None assert uri.port is None def test_handles_uri_with_path_and_query(self, uri_with_path_and_query): """ Test that URIReference can handle a URI with a path and query. """ uri = URIReference.from_string(uri_with_path_and_query) assert uri.scheme == 'http' assert uri.host == uri.authority assert uri.path == '/path/to/resource' assert uri.query == 'key=value' assert uri.fragment is None assert uri.userinfo is None assert uri.port is None def test_handles_uri_with_everything(self, uri_with_everything): """ Test that URIReference can handle and with everything in it. """ uri = URIReference.from_string(uri_with_everything) assert uri.scheme == 'https' assert uri.path == '/path/to/resource' assert uri.query == 'key=value' assert uri.fragment == 'fragment' assert uri.userinfo == 'user:pass' assert uri.port == '443' def test_authority_info_raises_InvalidAuthority(self, invalid_uri): """Test that an invalid IPv6 is caught by authority_info().""" uri = URIReference.from_string(invalid_uri) with pytest.raises(InvalidAuthority): uri.authority_info() def test_attributes_catch_InvalidAuthority(self, invalid_uri): """Test that an invalid IPv6 is caught by authority_info().""" uri = URIReference.from_string(invalid_uri) assert uri.host is None assert uri.userinfo is None assert uri.port is None def test_handles_relative_uri(self, relative_uri): """Test that URIReference can handle a relative URI.""" uri = URIReference.from_string(relative_uri) assert uri.scheme is None assert uri.authority == relative_uri[2:] def test_handles_absolute_path_uri(self, absolute_path_uri): """Test that URIReference can handle a path-only URI.""" uri = URIReference.from_string(absolute_path_uri) assert uri.path == absolute_path_uri assert uri.authority_info() == { 'userinfo': None, 'host': None, 'port': None, } def test_handles_scheme_and_path_uri(self, scheme_and_path_uri): """Test that URIReference can handle a `scheme:path` URI.""" uri = URIReference.from_string(scheme_and_path_uri) assert uri.path == 'user@example.com' assert uri.scheme == 'mailto' assert uri.query is None assert uri.host is None assert uri.port is None assert uri.userinfo is None assert uri.authority is None class TestURIValidation: # Valid URI tests def test_basic_uri_is_valid(self, basic_uri): uri = URIReference.from_string(basic_uri) assert uri.is_valid() is True def test_basic_uri_requiring_scheme(self, basic_uri): uri = URIReference.from_string(basic_uri) assert uri.is_valid(require_scheme=True) is True def test_basic_uri_requiring_authority(self, basic_uri): uri = URIReference.from_string(basic_uri) assert uri.is_valid(require_authority=True) is True def test_uri_with_everything_requiring_path(self, uri_with_everything): uri = URIReference.from_string(uri_with_everything) assert uri.is_valid(require_path=True) is True def test_uri_with_everything_requiring_query(self, uri_with_everything): uri = URIReference.from_string(uri_with_everything) assert uri.is_valid(require_query=True) is True def test_uri_with_everything_requiring_fragment(self, uri_with_everything): uri = URIReference.from_string(uri_with_everything) assert uri.is_valid(require_fragment=True) is True def test_basic_uri_with_port_is_valid(self, basic_uri_with_port): uri = URIReference.from_string(basic_uri_with_port) assert uri.is_valid() is True def test_uri_with_port_and_userinfo_is_valid(self, uri_with_port_and_userinfo): uri = URIReference.from_string(uri_with_port_and_userinfo) assert uri.is_valid() is True def test_basic_uri_with_path_is_valid(self, basic_uri_with_path): uri = URIReference.from_string(basic_uri_with_path) assert uri.is_valid() is True def test_uri_with_path_and_query_is_valid(self, uri_with_path_and_query): uri = URIReference.from_string(uri_with_path_and_query) assert uri.is_valid() is True def test_uri_with_everything_is_valid(self, uri_with_everything): uri = URIReference.from_string(uri_with_everything) assert uri.is_valid() is True def test_relative_uri_is_valid(self, relative_uri): uri = URIReference.from_string(relative_uri) assert uri.is_valid() is True def test_absolute_path_uri_is_valid(self, absolute_path_uri): uri = URIReference.from_string(absolute_path_uri) assert uri.is_valid() is True def test_scheme_and_path_uri_is_valid(self, scheme_and_path_uri): uri = URIReference.from_string(scheme_and_path_uri) assert uri.is_valid() is True # Invalid URI tests def test_invalid_uri_is_not_valid(self, invalid_uri): uri = URIReference.from_string(invalid_uri) assert uri.is_valid() is False def test_invalid_scheme(self): uri = URIReference('123', None, None, None, None) assert uri.is_valid() is False def test_invalid_path(self): uri = URIReference(None, None, 'foo#bar', None, None) assert uri.is_valid() is False def test_invalid_query_component(self): uri = URIReference(None, None, None, 'foo#bar', None) assert uri.is_valid() is False def test_invalid_fragment_component(self): uri = URIReference(None, None, None, None, 'foo#bar') assert uri.is_valid() is False class TestURIReferenceUnsplits: def test_basic_uri_unsplits(self, basic_uri): uri = URIReference.from_string(basic_uri) assert uri.unsplit() == basic_uri def test_basic_uri_with_port_unsplits(self, basic_uri_with_port): uri = URIReference.from_string(basic_uri_with_port) assert uri.unsplit() == basic_uri_with_port def test_uri_with_port_and_userinfo_unsplits(self, uri_with_port_and_userinfo): uri = URIReference.from_string(uri_with_port_and_userinfo) assert uri.unsplit() == uri_with_port_and_userinfo def test_basic_uri_with_path_unsplits(self, basic_uri_with_path): uri = URIReference.from_string(basic_uri_with_path) assert uri.unsplit() == basic_uri_with_path def test_uri_with_path_and_query_unsplits(self, uri_with_path_and_query): uri = URIReference.from_string(uri_with_path_and_query) assert uri.unsplit() == uri_with_path_and_query def test_uri_with_everything_unsplits(self, uri_with_everything): uri = URIReference.from_string(uri_with_everything) assert uri.unsplit() == uri_with_everything def test_relative_uri_unsplits(self, relative_uri): uri = URIReference.from_string(relative_uri) assert uri.unsplit() == relative_uri def test_absolute_path_uri_unsplits(self, absolute_path_uri): uri = URIReference.from_string(absolute_path_uri) assert uri.unsplit() == absolute_path_uri def test_scheme_and_path_uri_unsplits(self, scheme_and_path_uri): uri = URIReference.from_string(scheme_and_path_uri) assert uri.unsplit() == scheme_and_path_uri class TestURIReferenceComparesToStrings: def test_basic_uri(self, basic_uri): uri = URIReference.from_string(basic_uri) assert uri == basic_uri def test_basic_uri_with_port(self, basic_uri_with_port): uri = URIReference.from_string(basic_uri_with_port) assert uri == basic_uri_with_port def test_uri_with_port_and_userinfo(self, uri_with_port_and_userinfo): uri = URIReference.from_string(uri_with_port_and_userinfo) assert uri == uri_with_port_and_userinfo def test_basic_uri_with_path(self, basic_uri_with_path): uri = URIReference.from_string(basic_uri_with_path) assert uri == basic_uri_with_path def test_uri_with_path_and_query(self, uri_with_path_and_query): uri = URIReference.from_string(uri_with_path_and_query) assert uri == uri_with_path_and_query def test_uri_with_everything(self, uri_with_everything): uri = URIReference.from_string(uri_with_everything) assert uri == uri_with_everything def test_relative_uri(self, relative_uri): uri = URIReference.from_string(relative_uri) assert uri == relative_uri def test_absolute_path_uri(self, absolute_path_uri): uri = URIReference.from_string(absolute_path_uri) assert uri == absolute_path_uri def test_scheme_and_path_uri(self, scheme_and_path_uri): uri = URIReference.from_string(scheme_and_path_uri) assert uri == scheme_and_path_uri class TestURIReferenceComparesToTuples: def to_tuple(self, uri): return URI_MATCHER.match(uri).groups() def test_basic_uri(self, basic_uri): uri = URIReference.from_string(basic_uri) assert uri == self.to_tuple(basic_uri) def test_basic_uri_with_port(self, basic_uri_with_port): uri = URIReference.from_string(basic_uri_with_port) assert uri == self.to_tuple(basic_uri_with_port) def test_uri_with_port_and_userinfo(self, uri_with_port_and_userinfo): uri = URIReference.from_string(uri_with_port_and_userinfo) assert uri == self.to_tuple(uri_with_port_and_userinfo) def test_basic_uri_with_path(self, basic_uri_with_path): uri = URIReference.from_string(basic_uri_with_path) assert uri == self.to_tuple(basic_uri_with_path) def test_uri_with_path_and_query(self, uri_with_path_and_query): uri = URIReference.from_string(uri_with_path_and_query) assert uri == self.to_tuple(uri_with_path_and_query) def test_uri_with_everything(self, uri_with_everything): uri = URIReference.from_string(uri_with_everything) assert uri == self.to_tuple(uri_with_everything) def test_relative_uri(self, relative_uri): uri = URIReference.from_string(relative_uri) assert uri == self.to_tuple(relative_uri) def test_absolute_path_uri(self, absolute_path_uri): uri = URIReference.from_string(absolute_path_uri) assert uri == self.to_tuple(absolute_path_uri) def test_scheme_and_path_uri(self, scheme_and_path_uri): uri = URIReference.from_string(scheme_and_path_uri) assert uri == self.to_tuple(scheme_and_path_uri) def test_uri_comparison_raises_TypeError(basic_uri): uri = URIReference.from_string(basic_uri) with pytest.raises(TypeError): uri == 1 class TestURIReferenceComparesToURIReferences: def test_same_basic_uri(self, basic_uri): uri = URIReference.from_string(basic_uri) assert uri == uri def test_different_basic_uris(self, basic_uri, basic_uri_with_port): uri = URIReference.from_string(basic_uri) assert (uri == URIReference.from_string(basic_uri_with_port)) is False