MCP server for tangled
at main 2.9 kB view raw
1"""tests for public types API""" 2 3import pytest 4from pydantic import ValidationError 5 6from tangled_mcp.types import ( 7 CreateIssueResult, 8 ListBranchesResult, 9 UpdateIssueResult, 10) 11 12 13class TestRepoIdentifierValidation: 14 """test RepoIdentifier validation behavior""" 15 16 def test_strips_at_prefix(self): 17 """@ prefix is stripped during validation""" 18 result = CreateIssueResult(repo="@owner/repo", id=1) 19 assert result.repo == "owner/repo" 20 21 def test_accepts_without_at_prefix(self): 22 """repo identifier without @ works""" 23 result = CreateIssueResult(repo="owner/repo", id=1) 24 assert result.repo == "owner/repo" 25 26 def test_rejects_invalid_format(self): 27 """repo identifier without slash is rejected""" 28 with pytest.raises(ValidationError, match="invalid repo format"): 29 CreateIssueResult(repo="invalid", id=1) 30 31 32class TestIssueResultURLs: 33 """test issue result URL generation""" 34 35 def test_create_issue_url(self): 36 """create result generates correct tangled.org URL""" 37 result = CreateIssueResult(repo="owner/repo", id=42) 38 assert result.url == "https://tangled.org/@owner/repo/issues/42" 39 40 def test_update_issue_url(self): 41 """update result generates correct tangled.org URL""" 42 result = UpdateIssueResult(repo="owner/repo", id=42) 43 assert result.url == "https://tangled.org/@owner/repo/issues/42" 44 45 def test_url_handles_at_prefix_input(self): 46 """URL is correct even when input has @ prefix""" 47 result = CreateIssueResult(repo="@owner/repo", id=42) 48 assert result.url == "https://tangled.org/@owner/repo/issues/42" 49 50 def test_repo_excluded_from_serialization(self): 51 """repo field is excluded from JSON output""" 52 result = CreateIssueResult(repo="owner/repo", id=42) 53 data = result.model_dump() 54 assert "repo" not in data 55 assert data["id"] == 42 56 assert "url" in data 57 58 59class TestListBranchesFromAPIResponse: 60 """test ListBranchesResult.from_api_response constructor""" 61 62 def test_parses_branch_data(self): 63 """parses branches from API response structure""" 64 response = { 65 "branches": [ 66 {"reference": {"name": "main", "hash": "abc123"}}, 67 {"reference": {"name": "dev", "hash": "def456"}}, 68 ], 69 } 70 71 result = ListBranchesResult.from_api_response(response) 72 73 assert len(result.branches) == 2 74 assert result.branches[0].name == "main" 75 assert result.branches[0].sha == "abc123" 76 assert result.branches[1].name == "dev" 77 assert result.branches[1].sha == "def456" 78 79 def test_handles_empty_branches(self): 80 """handles empty branches list""" 81 response = {"branches": []} 82 83 result = ListBranchesResult.from_api_response(response) 84 85 assert result.branches == []