1010from strands .vended_plugins .skills ._url_loader import (
1111 fetch_skill_content ,
1212 is_url ,
13- resolve_to_raw_url ,
1413)
1514
1615
1716class TestIsUrl :
1817 """Tests for is_url."""
1918
2019 def test_https_url (self ):
21- assert is_url ("https://github .com/org/skill-repo " ) is True
20+ assert is_url ("https://example .com/SKILL.md " ) is True
2221
23- def test_https_raw_url (self ):
22+ def test_https_raw_github_url (self ):
2423 assert is_url ("https://raw.githubusercontent.com/org/repo/main/SKILL.md" ) is True
2524
2625 def test_http_rejected (self ):
2726 """Plaintext http:// is rejected for security."""
28- assert is_url ("http://github .com/org/skill-repo " ) is False
27+ assert is_url ("http://example .com/SKILL.md " ) is False
2928
3029 def test_ssh_rejected (self ):
31- """SSH URLs are not supported in HTTPS-only mode."""
32- assert is_url ("ssh://git@github.com/org/skill-repo" ) is False
30+ assert is_url ("ssh://git@github.com/org/repo" ) is False
3331
3432 def test_git_at_rejected (self ):
35- """git@ URLs are not supported in HTTPS-only mode."""
36- assert is_url ("git@github.com:org/skill-repo.git" ) is False
33+ assert is_url ("git@github.com:org/repo.git" ) is False
3734
3835 def test_local_relative_path (self ):
3936 assert is_url ("./skills/my-skill" ) is False
@@ -48,78 +45,6 @@ def test_empty_string(self):
4845 assert is_url ("" ) is False
4946
5047
51- class TestResolveToRawUrl :
52- """Tests for resolve_to_raw_url."""
53-
54- def test_raw_url_passthrough (self ):
55- url = "https://raw.githubusercontent.com/org/repo/main/SKILL.md"
56- assert resolve_to_raw_url (url ) == url
57-
58- def test_non_github_passthrough (self ):
59- url = "https://example.com/skills/SKILL.md"
60- assert resolve_to_raw_url (url ) == url
61-
62- def test_repo_root (self ):
63- assert resolve_to_raw_url ("https://github.com/org/repo" ) == (
64- "https://raw.githubusercontent.com/org/repo/HEAD/SKILL.md"
65- )
66-
67- def test_repo_root_trailing_slash (self ):
68- assert resolve_to_raw_url ("https://github.com/org/repo/" ) == (
69- "https://raw.githubusercontent.com/org/repo/HEAD/SKILL.md"
70- )
71-
72- def test_repo_root_with_ref (self ):
73- assert resolve_to_raw_url ("https://github.com/org/repo@v1.0.0" ) == (
74- "https://raw.githubusercontent.com/org/repo/v1.0.0/SKILL.md"
75- )
76-
77- def test_repo_root_with_branch_ref (self ):
78- assert resolve_to_raw_url ("https://github.com/org/repo@main" ) == (
79- "https://raw.githubusercontent.com/org/repo/main/SKILL.md"
80- )
81-
82- def test_tree_url_directory (self ):
83- assert resolve_to_raw_url ("https://github.com/org/repo/tree/main/skills/my-skill" ) == (
84- "https://raw.githubusercontent.com/org/repo/main/skills/my-skill/SKILL.md"
85- )
86-
87- def test_tree_url_branch_only (self ):
88- assert resolve_to_raw_url ("https://github.com/org/repo/tree/main" ) == (
89- "https://raw.githubusercontent.com/org/repo/main/SKILL.md"
90- )
91-
92- def test_tree_url_trailing_slash (self ):
93- assert resolve_to_raw_url ("https://github.com/org/repo/tree/main/skills/my-skill/" ) == (
94- "https://raw.githubusercontent.com/org/repo/main/skills/my-skill/SKILL.md"
95- )
96-
97- def test_tree_url_with_tag (self ):
98- assert resolve_to_raw_url ("https://github.com/org/repo/tree/v2.0/skills/brainstorming" ) == (
99- "https://raw.githubusercontent.com/org/repo/v2.0/skills/brainstorming/SKILL.md"
100- )
101-
102- def test_blob_url_to_skill_md (self ):
103- assert resolve_to_raw_url ("https://github.com/org/repo/blob/main/skills/my-skill/SKILL.md" ) == (
104- "https://raw.githubusercontent.com/org/repo/main/skills/my-skill/SKILL.md"
105- )
106-
107- def test_blob_url_to_lowercase_skill_md (self ):
108- assert resolve_to_raw_url ("https://github.com/org/repo/blob/main/skills/my-skill/skill.md" ) == (
109- "https://raw.githubusercontent.com/org/repo/main/skills/my-skill/skill.md"
110- )
111-
112- def test_unrecognized_github_path_passthrough (self ):
113- """Unrecognized GitHub URL patterns are returned as-is."""
114- url = "https://github.com/org/repo/wiki/Some-Page"
115- assert resolve_to_raw_url (url ) == url
116-
117- def test_github_deep_unrecognized_path (self ):
118- """GitHub URLs with more than owner/repo segments (not tree/blob) pass through."""
119- url = "https://github.com/org/repo/actions/runs/12345"
120- assert resolve_to_raw_url (url ) == url
121-
122-
12348class TestFetchSkillContent :
12449 """Tests for fetch_skill_content."""
12550
@@ -139,22 +64,33 @@ def test_fetch_success(self):
13964
14065 assert result == skill_content
14166
142- def test_fetch_resolves_github_url (self ):
143- """Test that GitHub web URLs are resolved before fetching ."""
144- skill_content = "--- \n name: test \n description: test \n --- \n "
67+ def test_fetch_uses_url_directly (self ):
68+ """Test that the URL is used as-is with no resolution ."""
69+ url = "https://raw.githubusercontent.com/org/repo/main/skills/my-skill/SKILL.md "
14570
14671 mock_response = MagicMock ()
147- mock_response .read .return_value = skill_content .encode ("utf-8" )
72+ mock_response .read .return_value = b"---\n name: t\n description: t\n ---\n "
73+ mock_response .__enter__ = MagicMock (return_value = mock_response )
74+ mock_response .__exit__ = MagicMock (return_value = False )
75+
76+ with patch (f"{ self ._LOADER } .urllib.request.urlopen" , return_value = mock_response ) as mock_urlopen :
77+ fetch_skill_content (url )
78+
79+ request_obj = mock_urlopen .call_args [0 ][0 ]
80+ assert request_obj .full_url == url
81+
82+ def test_fetch_sets_user_agent (self ):
83+ """Test that requests include a User-Agent header."""
84+ mock_response = MagicMock ()
85+ mock_response .read .return_value = b"---\n name: t\n description: t\n ---\n "
14886 mock_response .__enter__ = MagicMock (return_value = mock_response )
14987 mock_response .__exit__ = MagicMock (return_value = False )
15088
15189 with patch (f"{ self ._LOADER } .urllib.request.urlopen" , return_value = mock_response ) as mock_urlopen :
152- fetch_skill_content ("https://github .com/org/repo/tree/main/skills/my-skill " )
90+ fetch_skill_content ("https://example .com/SKILL.md " )
15391
154- # Verify the resolved raw URL was used
155- call_args = mock_urlopen .call_args
156- request_obj = call_args [0 ][0 ]
157- assert "raw.githubusercontent.com" in request_obj .full_url
92+ request_obj = mock_urlopen .call_args [0 ][0 ]
93+ assert request_obj .get_header ("User-agent" ) == "strands-agents-sdk"
15894
15995 def test_fetch_http_error (self ):
16096 """Test that HTTP errors raise RuntimeError."""
0 commit comments