diff --git a/python/numbersprotocol_capture/verify.py b/python/numbersprotocol_capture/verify.py index 2f93993..d8704d1 100644 --- a/python/numbersprotocol_capture/verify.py +++ b/python/numbersprotocol_capture/verify.py @@ -5,7 +5,7 @@ digital asset provenance. """ -from urllib.parse import urlencode +from urllib.parse import quote, urlencode VERIFY_BASE_URL = "https://verify.numbersprotocol.io" @@ -24,7 +24,7 @@ def search_by_nid(nid: str) -> str: >>> url = search_by_nid("bafybei...") >>> # => "https://verify.numbersprotocol.io/search?nid=bafybei..." """ - return f"{VERIFY_BASE_URL}/search?nid={nid}" + return f"{VERIFY_BASE_URL}/search?nid={quote(nid, safe='')}" def search_by_nft(token_id: str, contract: str) -> str: @@ -60,7 +60,7 @@ def asset_profile(nid: str) -> str: >>> url = asset_profile("bafybei...") >>> # => "https://verify.numbersprotocol.io/asset-profile?nid=bafybei..." """ - return f"{VERIFY_BASE_URL}/asset-profile?nid={nid}" + return f"{VERIFY_BASE_URL}/asset-profile?nid={quote(nid, safe='')}" def asset_profile_by_nft(token_id: str, contract: str) -> str: diff --git a/python/tests/test_verify.py b/python/tests/test_verify.py new file mode 100644 index 0000000..0919efc --- /dev/null +++ b/python/tests/test_verify.py @@ -0,0 +1,69 @@ +""" +Unit tests for Verify Engine URL helpers. +""" + +import pytest + +from numbersprotocol_capture.verify import ( + VERIFY_BASE_URL, + asset_profile, + asset_profile_by_nft, + search_by_nft, + search_by_nid, +) + +NORMAL_NID = "bafybeif3mhxhkhfwuszl2lybtai3hz3q6naqpfisd4q55mcc7opkmiv5ei" + + +class TestSearchByNid: + def test_normal_nid(self): + url = search_by_nid(NORMAL_NID) + assert url == f"{VERIFY_BASE_URL}/search?nid={NORMAL_NID}" + + def test_special_characters_are_encoded(self): + url = search_by_nid("nid with spaces¶m=injected") + assert " " not in url + assert "¶m=injected" not in url + assert url == f"{VERIFY_BASE_URL}/search?nid=nid%20with%20spaces%26param%3Dinjected" + + def test_hash_character_is_encoded(self): + url = search_by_nid("nid#fragment") + assert "#" not in url + assert url == f"{VERIFY_BASE_URL}/search?nid=nid%23fragment" + + +class TestAssetProfile: + def test_normal_nid(self): + url = asset_profile(NORMAL_NID) + assert url == f"{VERIFY_BASE_URL}/asset-profile?nid={NORMAL_NID}" + + def test_special_characters_are_encoded(self): + url = asset_profile("nid with spaces¶m=injected") + assert " " not in url + assert "¶m=injected" not in url + assert url == f"{VERIFY_BASE_URL}/asset-profile?nid=nid%20with%20spaces%26param%3Dinjected" + + def test_hash_character_is_encoded(self): + url = asset_profile("nid#fragment") + assert "#" not in url + assert url == f"{VERIFY_BASE_URL}/asset-profile?nid=nid%23fragment" + + +class TestSearchByNft: + def test_normal_nft(self): + url = search_by_nft("123", "0x1234abcd") + assert url == f"{VERIFY_BASE_URL}/search?nft=123&contract=0x1234abcd" + + def test_special_characters_are_encoded(self): + url = search_by_nft("token id with space", "0x1234") + assert "token+id+with+space" in url or "token%20id%20with%20space" in url + + +class TestAssetProfileByNft: + def test_normal_nft(self): + url = asset_profile_by_nft("123", "0x1234abcd") + assert url == f"{VERIFY_BASE_URL}/asset-profile?nft=123&contract=0x1234abcd" + + def test_special_characters_are_encoded(self): + url = asset_profile_by_nft("token id with space", "0x1234") + assert "token+id+with+space" in url or "token%20id%20with%20space" in url