MCP server for tangled
at main 98 lines 3.6 kB view raw
1"""tests for repository identifier resolution""" 2 3import pytest 4 5from tangled_mcp._tangled._client import _extract_error_message 6 7 8class TestExtractErrorMessage: 9 """test error message extraction from various exception types""" 10 11 def test_extracts_from_atproto_response(self): 12 """extracts message from atproto RequestErrorBase structure""" 13 14 class MockContent: 15 message = "handle must be a valid handle" 16 17 class MockResponse: 18 content = MockContent() 19 20 class MockException(Exception): 21 response = MockResponse() 22 23 msg = _extract_error_message(MockException()) 24 assert msg == "handle must be a valid handle" 25 26 def test_truncates_long_messages(self): 27 """truncates messages longer than 200 chars""" 28 long_msg = "x" * 300 29 30 class MockException(Exception): 31 pass 32 33 e = MockException(long_msg) 34 msg = _extract_error_message(e) 35 assert len(msg) == 203 # 200 + "..." 36 assert msg.endswith("...") 37 38 def test_handles_none_response(self): 39 """handles exception with None response""" 40 41 class MockException(Exception): 42 response = None 43 44 e = MockException("fallback message") 45 msg = _extract_error_message(e) 46 assert msg == "fallback message" 47 48 49class TestRepoIdentifierParsing: 50 """test repository identifier format validation""" 51 52 def test_invalid_format_no_slash(self): 53 """test that identifiers without slash are rejected""" 54 from tangled_mcp._tangled._client import resolve_repo_identifier 55 56 with pytest.raises( 57 ValueError, match="invalid repo format.*expected 'owner/repo'" 58 ): 59 resolve_repo_identifier("invalid") 60 61 def test_invalid_format_empty(self): 62 """test that empty identifiers are rejected""" 63 from tangled_mcp._tangled._client import resolve_repo_identifier 64 65 with pytest.raises( 66 ValueError, match="invalid repo format.*expected 'owner/repo'" 67 ): 68 resolve_repo_identifier("") 69 70 def test_valid_format_with_handle(self): 71 """test that valid owner/repo format is accepted (parsing only)""" 72 # note: we can't actually test resolution without credentials 73 # but we can test that the format parsing works 74 from tangled_mcp._tangled._client import resolve_repo_identifier 75 76 # this will fail at the resolution step, but not at parsing 77 with pytest.raises(Exception): # will fail during actual resolution 78 resolve_repo_identifier("owner/repo") 79 80 def test_valid_format_with_at_prefix(self): 81 """test that @owner/repo and owner/repo resolve identically""" 82 from tangled_mcp._tangled._client import resolve_repo_identifier 83 84 # both formats should behave the same (@ is stripped internally) 85 # they'll both fail resolution with fake handle, but in the same way 86 with pytest.raises(ValueError, match="failed to resolve handle 'owner'"): 87 resolve_repo_identifier("@owner/repo") 88 89 with pytest.raises(ValueError, match="failed to resolve handle 'owner'"): 90 resolve_repo_identifier("owner/repo") 91 92 def test_valid_format_with_did(self): 93 """test that did:plc:.../repo format is accepted""" 94 from tangled_mcp._tangled._client import resolve_repo_identifier 95 96 # this will fail at the resolution step, but not at parsing 97 with pytest.raises(Exception): # will fail during actual resolution 98 resolve_repo_identifier("did:plc:test123/repo")