diff --git a/tests/test_locations.py b/tests/test_locations.py index 0340adb9..5c61f666 100644 --- a/tests/test_locations.py +++ b/tests/test_locations.py @@ -345,7 +345,8 @@ def test_normalize_url_unc_paths__issue_268(self,): self.assertNotEqual(path.as_uri(), url) self.assertEqual(normalize_url(unc_path), url_host_in_path) - def test_normalize_url_with_base_unc_path(self,): + @unittest.skipIf(platform.system() != 'Windows', "Run only on Windows systems") + def test_normalize_url_with_base_unc_path_on_windows(self,): base_unc_path = '\\\\filer01\\MY_HOME\\' base_url = PureWindowsPath(base_unc_path).as_uri() self.assertEqual(str(PureWindowsPath(base_unc_path)), base_unc_path) @@ -357,6 +358,51 @@ def test_normalize_url_with_base_unc_path(self,): self.assertEqual(normalize_url(base_unc_path), base_url_host_in_path) + self.assertEqual(os.name, 'nt') + path = PurePath('dir/file') + self.assertIs(path.__class__, PureWindowsPath) + + url = normalize_url(r'dev\XMLSCHEMA\test.xsd', base_url=base_unc_path) + self.assertEqual(url, 'file:////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') + + url = normalize_url(r'dev\XMLSCHEMA\test.xsd', base_url=base_url) + self.assertEqual(url, 'file:////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') + + url = normalize_url(r'dev\XMLSCHEMA\test.xsd', base_url=base_url_host_in_path) + if is_unc_path('////filer01/MY_HOME/'): + self.assertEqual(url, 'file://////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') + else: + self.assertRegex( + url, f'file://{DRIVE_REGEX}/filer01/MY_HOME/dev/XMLSCHEMA/test.xsd' + ) + + @unittest.skipIf(platform.system() == 'Windows', "Skip on Windows systems") + def test_normalize_url_with_base_unc_path_on_others(self,): + base_unc_path = '\\\\filer01\\MY_HOME\\' + base_url = PureWindowsPath(base_unc_path).as_uri() + self.assertEqual(str(PureWindowsPath(base_unc_path)), base_unc_path) + self.assertEqual(base_url, 'file://filer01/MY_HOME/') + + # Same UNC path as URI with the host inserted in path + base_url_host_in_path = base_url.replace('file://', 'file:////') + self.assertEqual(base_url_host_in_path, 'file:////filer01/MY_HOME/') + + self.assertEqual(normalize_url(base_unc_path), base_url_host_in_path) + + url = normalize_url(r'dev\XMLSCHEMA\test.xsd', base_url=base_unc_path) + self.assertEqual(url, 'file:////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') + + url = normalize_url(r'dev/XMLSCHEMA/test.xsd', base_url=base_url) + self.assertEqual(url, 'file:////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') + + url = normalize_url(r'dev/XMLSCHEMA/test.xsd', base_url=base_url_host_in_path) + if is_unc_path('////'): + self.assertEqual(url, 'file://////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') + else: + self.assertRegex( + url, f'file://{DRIVE_REGEX}/filer01/MY_HOME/dev/XMLSCHEMA/test.xsd' + ) + with patch.object(os, 'name', 'nt'): self.assertEqual(os.name, 'nt') path = PurePath('dir/file') @@ -376,25 +422,6 @@ def test_normalize_url_with_base_unc_path(self,): url, f'file://{DRIVE_REGEX}/filer01/MY_HOME/dev/XMLSCHEMA/test.xsd' ) - with patch.object(os, 'name', 'posix'): - self.assertEqual(os.name, 'posix') - path = PurePath('dir/file') - self.assertIs(path.__class__, PurePosixPath) - - url = normalize_url(r'dev\XMLSCHEMA\test.xsd', base_url=base_unc_path) - self.assertEqual(url, 'file:////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') - - url = normalize_url(r'dev/XMLSCHEMA/test.xsd', base_url=base_url) - self.assertEqual(url, 'file:////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') - - url = normalize_url(r'dev/XMLSCHEMA/test.xsd', base_url=base_url_host_in_path) - if is_unc_path('////'): - self.assertEqual(url, 'file://////filer01/MY_HOME/dev/XMLSCHEMA/test.xsd') - else: - self.assertRegex( - url, f'file://{DRIVE_REGEX}/filer01/MY_HOME/dev/XMLSCHEMA/test.xsd' - ) - def test_normalize_url_slashes(self): # Issue #116 url = '//anaconda/envs/testenv/lib/python3.6/site-packages/xmlschema/validators/schemas/' @@ -475,6 +502,35 @@ def test_normalize_url_with_query_part(self): self.check_url(normalize_url('other.xsd#element', 'https://host/path?name=2&id='), 'https://host/path/other.xsd#element') + def test_normalize_url_with_local_part(self): + # https://datatracker.ietf.org/doc/html/rfc8089#appendix-E.2 + + url = "file:c:/path/to/file" + self.assertEqual(urlsplit(url).geturl(), 'file:///c:/path/to/file') + self.assertEqual(normalize_url(url), 'file:///c:/path/to/file') + + url = "file:///c:/path/to/file" + self.assertEqual(urlsplit(url).geturl(), url) + self.assertEqual(normalize_url(url), url) + + base_url = "file:///D:/a/xmlschema/xmlschema/filer01/MY_HOME" + url = normalize_url(r'dev/XMLSCHEMA/test.xsd', base_url) + self.assertEqual( + url, "file:///D:/a/xmlschema/xmlschema/filer01/MY_HOME/dev/XMLSCHEMA/test.xsd" + ) + + base_url = "file:D:/a/xmlschema/xmlschema/filer01/MY_HOME" + url = normalize_url(r'dev/XMLSCHEMA/test.xsd', base_url) + self.assertEqual( + url, "file:///D:/a/xmlschema/xmlschema/filer01/MY_HOME/dev/XMLSCHEMA/test.xsd" + ) + + base_url = "D:\\a\\xmlschema\\xmlschema/\\/filer01/MY_HOME" + url = normalize_url(r'dev/XMLSCHEMA/test.xsd', base_url) + self.assertEqual( + url, "file:///D:/a/xmlschema/xmlschema/filer01/MY_HOME/dev/XMLSCHEMA/test.xsd" + ) + def test_is_url_function(self): self.assertTrue(is_url(self.col_xsd_file)) self.assertFalse(is_url('http://example.com[')) diff --git a/xmlschema/locations.py b/xmlschema/locations.py index 17551bcc..622d4253 100644 --- a/xmlschema/locations.py +++ b/xmlschema/locations.py @@ -179,7 +179,7 @@ def get_uri(scheme: str = '', authority: str = '', path: str = '', if fragment: url = url + '#' + fragment - return url.rstrip() + return url def normalize_url(url: str, base_url: Optional[str] = None, @@ -200,7 +200,7 @@ def normalize_url(url: str, base_url: Optional[str] = None, """ url_parts = urlsplit(url.lstrip()) if not is_local_scheme(url_parts.scheme): - return encode_url(url_parts.geturl(), method) + return encode_url(get_uri(*url_parts), method) path = LocationPath.from_uri(url) if path.is_absolute():