We've slightly modified the URI_MATCHER regular expression components to avoid parsing the plain string "[::1]" as having a scheme of "[" and host of ":1]". That said, Junk is passed in and Junk was returned so, it's not exactly the most ideal thing, it just makes our lives a little less awful since we can avoid it.
354 lines
13 KiB
Python
354 lines
13 KiB
Python
# -*- coding: utf-8 -*-
|
|
import pytest
|
|
|
|
from rfc3986.exceptions import InvalidAuthority, ResolutionError
|
|
from rfc3986.misc import URI_MATCHER
|
|
from rfc3986.uri import URIReference
|
|
|
|
from . import base
|
|
|
|
|
|
@pytest.fixture
|
|
def scheme_and_path_uri():
|
|
return 'mailto:user@example.com'
|
|
|
|
|
|
class TestURIReferenceParsesURIs(base.BaseTestParsesURIs):
|
|
"""Tests for URIReference handling of URIs."""
|
|
test_class = URIReference
|
|
|
|
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_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_scheme_and_path_uri_is_valid(self, scheme_and_path_uri):
|
|
uri = self.test_class.from_string(scheme_and_path_uri)
|
|
assert uri.is_valid() is True
|
|
|
|
def test_handles_scheme_and_path_uri(self, scheme_and_path_uri):
|
|
"""Test that self.test_class can handle a `scheme:path` URI."""
|
|
uri = self.test_class.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
|
|
|
|
def test_parses_ipv6_to_path(self):
|
|
"""Verify that we don't parse [ as a scheme."""
|
|
uri = self.test_class.from_string('[::1]')
|
|
assert uri.scheme is None
|
|
assert uri.authority is None
|
|
assert uri.path == '[::1]'
|
|
|
|
|
|
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(base.BaseTestUnsplits):
|
|
test_class = URIReference
|
|
|
|
def test_scheme_and_path_uri_unsplits(self, scheme_and_path_uri):
|
|
uri = self.test_class.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
|
|
|
|
|
|
class TestURIReferenceIsAbsolute:
|
|
def test_basic_uris_are_absolute(self, basic_uri):
|
|
uri = URIReference.from_string(basic_uri)
|
|
assert uri.is_absolute() is True
|
|
|
|
def test_basic_uris_with_ports_are_absolute(self, basic_uri_with_port):
|
|
uri = URIReference.from_string(basic_uri_with_port)
|
|
assert uri.is_absolute() is True
|
|
|
|
def test_basic_uris_with_paths_are_absolute(self, basic_uri_with_path):
|
|
uri = URIReference.from_string(basic_uri_with_path)
|
|
assert uri.is_absolute() is True
|
|
|
|
def test_uri_with_everything_are_not_absolute(self, uri_with_everything):
|
|
uri = URIReference.from_string(uri_with_everything)
|
|
assert uri.is_absolute() is False
|
|
|
|
def test_absolute_paths_are_not_absolute_uris(self, absolute_path_uri):
|
|
uri = URIReference.from_string(absolute_path_uri)
|
|
assert uri.is_absolute() is False
|
|
|
|
|
|
# @pytest.fixture(params=[
|
|
# basic_uri, basic_uri_with_port, basic_uri_with_path,
|
|
# scheme_and_path_uri, uri_with_path_and_query
|
|
# ])
|
|
# @pytest.fixture(params=[absolute_path_uri, relative_uri])
|
|
|
|
|
|
class TestURIReferencesResolve:
|
|
def test_with_basic_and_relative_uris(self, basic_uri, relative_uri):
|
|
R = URIReference.from_string(relative_uri)
|
|
B = URIReference.from_string(basic_uri)
|
|
T = R.resolve_with(basic_uri)
|
|
assert T.scheme == B.scheme
|
|
assert T.host == R.host
|
|
assert T.path == R.path
|
|
|
|
def test_with_basic_and_absolute_path_uris(self, basic_uri,
|
|
absolute_path_uri):
|
|
R = URIReference.from_string(absolute_path_uri)
|
|
B = URIReference.from_string(basic_uri).normalize()
|
|
T = R.resolve_with(B)
|
|
assert T.scheme == B.scheme
|
|
assert T.host == B.host
|
|
assert T.path == R.path
|
|
|
|
def test_with_basic_uri_and_relative_path(self, basic_uri):
|
|
R = URIReference.from_string('foo/bar/bogus')
|
|
B = URIReference.from_string(basic_uri).normalize()
|
|
T = R.resolve_with(B)
|
|
assert T.scheme == B.scheme
|
|
assert T.host == B.host
|
|
assert T.path == '/' + R.path
|
|
|
|
def test_basic_uri_with_path_and_relative_path(self, basic_uri_with_path):
|
|
R = URIReference.from_string('foo/bar/bogus')
|
|
B = URIReference.from_string(basic_uri_with_path).normalize()
|
|
T = R.resolve_with(B)
|
|
assert T.scheme == B.scheme
|
|
assert T.host == B.host
|
|
|
|
index = B.path.rfind('/')
|
|
assert T.path == B.path[:index] + '/' + R.path
|
|
|
|
def test_uri_with_everything_raises_exception(self, uri_with_everything):
|
|
R = URIReference.from_string('foo/bar/bogus')
|
|
B = URIReference.from_string(uri_with_everything)
|
|
with pytest.raises(ResolutionError):
|
|
R.resolve_with(B)
|
|
|
|
def test_basic_uri_resolves_itself(self, basic_uri):
|
|
R = URIReference.from_string(basic_uri)
|
|
B = URIReference.from_string(basic_uri)
|
|
T = R.resolve_with(B)
|
|
assert T == B
|
|
|
|
def test_differing_schemes(self, basic_uri):
|
|
R = URIReference.from_string('https://example.com/path')
|
|
B = URIReference.from_string(basic_uri)
|
|
T = R.resolve_with(B)
|
|
assert T.scheme == R.scheme
|
|
|
|
def test_resolve_pathless_fragment(self, basic_uri):
|
|
R = URIReference.from_string('#fragment')
|
|
B = URIReference.from_string(basic_uri)
|
|
T = R.resolve_with(B)
|
|
assert T.path is None
|
|
assert T.fragment == 'fragment'
|
|
|
|
def test_resolve_pathless_query(self, basic_uri):
|
|
R = URIReference.from_string('?query')
|
|
B = URIReference.from_string(basic_uri)
|
|
T = R.resolve_with(B)
|
|
assert T.path is None
|
|
assert T.query == 'query'
|
|
|
|
|
|
def test_empty_querystrings_persist():
|
|
url = 'https://httpbin.org/get?'
|
|
ref = URIReference.from_string(url)
|
|
assert ref.query == ''
|
|
assert ref.unsplit() == url
|