Skip to content

Commit 02b9671

Browse files
committed
Add tests
Signed-off-by: Tushar Goel <[email protected]>
1 parent 0838daf commit 02b9671

File tree

2 files changed

+59
-9
lines changed

2 files changed

+59
-9
lines changed

src/fetchcode/__init__.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ def resolve_purl(purl):
9696
"""
9797
Resolve a Package URL (PURL) to a download URL.
9898
99-
This function attempts to resolve the PURL using both the purl2url library and
100-
the fetchcode.download_urls module. It returns the first valid download URL found.
99+
This function attempts to resolve the PURL using first purl2url library and
100+
if that fails, it falls back to fetchcode's download_urls module.
101101
"""
102102
from fetchcode.download_urls import download_url as get_download_url_from_fetchcode
103103

@@ -107,18 +107,47 @@ def resolve_purl(purl):
107107
return url
108108

109109

110+
def get_resolved_url(url, scheme):
111+
resoltion_by_scheme = {
112+
"pkg": resolve_url_from_purl,
113+
}
114+
resolution_handler = resoltion_by_scheme.get(scheme)
115+
if not resolution_handler:
116+
raise ValueError(f"Not a supported/known scheme: {scheme}")
117+
url, scheme = resolution_handler(url)
118+
return url, scheme
119+
120+
121+
def resolve_url_from_purl(url):
122+
"""
123+
Resolve a Package URL (PURL) to a valid URL.
124+
Raises ValueError if the PURL cannot be resolved.
125+
"""
126+
url = resolve_purl(url)
127+
if not url:
128+
raise ValueError("Could not resolve PURL to a valid URL.")
129+
scheme = get_url_scheme(url)
130+
return url, scheme
131+
132+
133+
def get_url_scheme(url):
134+
"""
135+
Return the scheme of the given URL.
136+
"""
137+
url_parts = urlparse(url)
138+
scheme = url_parts.scheme
139+
return scheme
140+
141+
110142
def fetch(url):
111143
"""
112144
Return a `Response` object built from fetching the content at the `url` URL string and
113145
store content at a temporary file.
114146
"""
115-
url_parts = urlparse(url)
116-
scheme = url_parts.scheme
147+
scheme = get_url_scheme(url)
117148

118-
if scheme == "pkg":
119-
url = resolve_purl(url)
120-
url_parts = urlparse(url)
121-
scheme = url_parts.scheme
149+
if scheme in ["pkg"]:
150+
url, scheme = get_resolved_url(url, scheme)
122151

123152
temp = tempfile.NamedTemporaryFile(delete=False)
124153
location = temp.name
@@ -128,7 +157,7 @@ def fetch(url):
128157
if scheme in fetchers:
129158
return fetchers.get(scheme)(url, location)
130159

131-
raise Exception("Not a supported/known scheme.")
160+
raise Exception(f"Not a supported/known scheme: {scheme}.")
132161

133162

134163
def fetch_json_response(url):

tests/test_fetch.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,24 @@ def test_fetch_with_scheme_not_present():
6363
url = "abc://speedtest/1KB.zip"
6464
response = fetch(url=url)
6565
assert "Not a supported/known scheme." == e_info
66+
67+
68+
@mock.patch("fetchcode.resolve_url_from_purl")
69+
@mock.patch("fetchcode.fetch_http")
70+
def test_fetch_purl(mock_fetch_http, mock_resolve):
71+
mock_fetch_http.return_value = "mocked_purl_response"
72+
mock_resolve.return_value = ("http://resolved.com/file.tar.gz", "http")
73+
74+
response = fetch("pkg:pypi/[email protected]")
75+
76+
assert response == "mocked_purl_response"
77+
mock_resolve.assert_called_once()
78+
mock_fetch_http.assert_called_once()
79+
80+
81+
@mock.patch("fetchcode.get_url_scheme")
82+
def test_fetch_unsupported_scheme(mock_get_scheme):
83+
mock_get_scheme.return_value = "s3"
84+
85+
with pytest.raises(Exception, match="Not a supported/known scheme"):
86+
fetch("s3://bucket/object")

0 commit comments

Comments
 (0)