@@ -21,6 +21,7 @@ import (
21
21
gogithub "github.com/google/go-github/v73/github"
22
22
mcpClient "github.com/mark3labs/mcp-go/client"
23
23
"github.com/mark3labs/mcp-go/mcp"
24
+ "github.com/stretchr/testify/assert"
24
25
"github.com/stretchr/testify/require"
25
26
)
26
27
@@ -1624,3 +1625,155 @@ func TestPullRequestReviewDeletion(t *testing.T) {
1624
1625
require .NoError (t , err , "expected to unmarshal text content successfully" )
1625
1626
require .Len (t , noReviews , 0 , "expected to find no reviews" )
1626
1627
}
1628
+
1629
+ func TestFindClosingPullRequests (t * testing.T ) {
1630
+ t .Parallel ()
1631
+
1632
+ mcpClient := setupMCPClient (t , withToolsets ([]string {"issues" }))
1633
+
1634
+ ctx := context .Background ()
1635
+
1636
+ // Test with well-known GitHub repositories and issues
1637
+ testCases := []struct {
1638
+ name string
1639
+ issues []interface {}
1640
+ limit int
1641
+ expectError bool
1642
+ expectedResults int
1643
+ expectSomeWithClosingPR bool
1644
+ }{
1645
+ {
1646
+ name : "Single issue test - should handle gracefully even if no closing PRs" ,
1647
+ issues : []interface {}{"octocat/Hello-World#1" },
1648
+ limit : 5 ,
1649
+ expectError : false ,
1650
+ expectedResults : 1 ,
1651
+ },
1652
+ {
1653
+ name : "Multiple issues test" ,
1654
+ issues : []interface {}{"octocat/Hello-World#1" , "github/docs#1" },
1655
+ limit : 3 ,
1656
+ expectError : false ,
1657
+ expectedResults : 2 ,
1658
+ },
1659
+ {
1660
+ name : "Invalid issue format should return error" ,
1661
+ issues : []interface {}{"invalid-format" },
1662
+ expectError : true ,
1663
+ },
1664
+ {
1665
+ name : "Empty issues array should return error" ,
1666
+ issues : []interface {}{},
1667
+ expectError : true ,
1668
+ },
1669
+ {
1670
+ name : "Limit too high should return error" ,
1671
+ issues : []interface {}{"octocat/Hello-World#1" },
1672
+ limit : 150 ,
1673
+ expectError : true ,
1674
+ },
1675
+ }
1676
+
1677
+ for _ , tc := range testCases {
1678
+ t .Run (tc .name , func (t * testing.T ) {
1679
+ // Prepare the request
1680
+ findClosingPRsRequest := mcp.CallToolRequest {}
1681
+ findClosingPRsRequest .Params .Name = "find_closing_pull_requests"
1682
+
1683
+ // Build arguments map
1684
+ args := map [string ]any {
1685
+ "issues" : tc .issues ,
1686
+ }
1687
+ if tc .limit > 0 {
1688
+ args ["limit" ] = tc .limit
1689
+ }
1690
+ findClosingPRsRequest .Params .Arguments = args
1691
+
1692
+ t .Logf ("Calling find_closing_pull_requests with issues: %v" , tc .issues )
1693
+ resp , err := mcpClient .CallTool (ctx , findClosingPRsRequest )
1694
+
1695
+ if tc .expectError {
1696
+ // We expect either an error or an error response
1697
+ if err != nil {
1698
+ t .Logf ("Expected error occurred: %v" , err )
1699
+ return
1700
+ }
1701
+ require .True (t , resp .IsError , "Expected error response" )
1702
+ t .Logf ("Expected error in response: %+v" , resp )
1703
+ return
1704
+ }
1705
+
1706
+ require .NoError (t , err , "expected to call 'find_closing_pull_requests' tool successfully" )
1707
+ require .False (t , resp .IsError , fmt .Sprintf ("expected result not to be an error: %+v" , resp ))
1708
+
1709
+ // Verify we got content
1710
+ require .NotEmpty (t , resp .Content , "Expected response content" )
1711
+
1712
+ textContent , ok := resp .Content [0 ].(mcp.TextContent )
1713
+ require .True (t , ok , "expected content to be of type TextContent" )
1714
+
1715
+ t .Logf ("Response: %s" , textContent .Text )
1716
+
1717
+ // Parse the JSON response
1718
+ var response struct {
1719
+ Results []struct {
1720
+ Issue string `json:"issue"`
1721
+ Owner string `json:"owner"`
1722
+ Repo string `json:"repo"`
1723
+ IssueNumber int `json:"issueNumber"`
1724
+ ClosingPullRequests []struct {
1725
+ Number int `json:"number"`
1726
+ Title string `json:"title"`
1727
+ Body string `json:"body"`
1728
+ State string `json:"state"`
1729
+ URL string `json:"url"`
1730
+ Merged bool `json:"merged"`
1731
+ } `json:"closingPullRequests"`
1732
+ TotalCount int `json:"totalCount"`
1733
+ Error string `json:"error,omitempty"`
1734
+ } `json:"results"`
1735
+ }
1736
+
1737
+ err = json .Unmarshal ([]byte (textContent .Text ), & response )
1738
+ require .NoError (t , err , "expected to unmarshal response successfully" )
1739
+
1740
+ // Verify the response structure
1741
+ require .Len (t , response .Results , tc .expectedResults , "Expected specific number of results" )
1742
+
1743
+ // Log and verify each result
1744
+ for i , result := range response .Results {
1745
+ t .Logf ("Result %d:" , i + 1 )
1746
+ t .Logf (" Issue: %s" , result .Issue )
1747
+ t .Logf (" Owner: %s, Repo: %s, Number: %d" , result .Owner , result .Repo , result .IssueNumber )
1748
+ t .Logf (" Total closing PRs: %d" , result .TotalCount )
1749
+ if result .Error != "" {
1750
+ t .Logf (" Error: %s" , result .Error )
1751
+ }
1752
+
1753
+ // Verify basic structure
1754
+ assert .NotEmpty (t , result .Issue , "Issue reference should not be empty" )
1755
+ assert .NotEmpty (t , result .Owner , "Owner should not be empty" )
1756
+ assert .NotEmpty (t , result .Repo , "Repo should not be empty" )
1757
+ assert .Greater (t , result .IssueNumber , 0 , "Issue number should be positive" )
1758
+
1759
+ // Log details of any closing PRs found
1760
+ for j , pr := range result .ClosingPullRequests {
1761
+ t .Logf (" Closing PR %d:" , j + 1 )
1762
+ t .Logf (" Number: %d" , pr .Number )
1763
+ t .Logf (" Title: %s" , pr .Title )
1764
+ t .Logf (" State: %s, Merged: %t" , pr .State , pr .Merged )
1765
+ t .Logf (" URL: %s" , pr .URL )
1766
+
1767
+ // Verify PR structure
1768
+ assert .Greater (t , pr .Number , 0 , "PR number should be positive" )
1769
+ assert .NotEmpty (t , pr .Title , "PR title should not be empty" )
1770
+ assert .NotEmpty (t , pr .State , "PR state should not be empty" )
1771
+ assert .NotEmpty (t , pr .URL , "PR URL should not be empty" )
1772
+ }
1773
+
1774
+ // The actual count of closing PRs should match the returned array length
1775
+ assert .Equal (t , len (result .ClosingPullRequests ), result .TotalCount , "ClosingPullRequests length should match TotalCount" )
1776
+ }
1777
+ })
1778
+ }
1779
+ }
0 commit comments