@@ -1528,3 +1528,157 @@ func Test_ListBranches(t *testing.T) {
15281528 })
15291529 }
15301530}
1531+
1532+ func Test_CreateRepositoryFromTemplate (t * testing.T ) {
1533+ // Verify tool definition once
1534+ mockClient := github .NewClient (nil )
1535+ tool , _ := CreateRepositoryFromTemplate (stubGetClientFn (mockClient ), translations .NullTranslationHelper )
1536+
1537+ assert .Equal (t , "create_repository_from_template" , tool .Name )
1538+ assert .NotEmpty (t , tool .Description )
1539+ assert .Contains (t , tool .InputSchema .Properties , "name" )
1540+ assert .Contains (t , tool .InputSchema .Properties , "description" )
1541+ assert .Contains (t , tool .InputSchema .Properties , "private" )
1542+ assert .Contains (t , tool .InputSchema .Properties , "includeAllBranches" )
1543+ assert .Contains (t , tool .InputSchema .Properties , "templateOwner" )
1544+ assert .Contains (t , tool .InputSchema .Properties , "templateRepo" )
1545+ assert .ElementsMatch (t , tool .InputSchema .Required , []string {"name" , "templateOwner" , "templateRepo" })
1546+
1547+ // Setup mock repository response
1548+ mockRepo := & github.Repository {
1549+ Name : github .Ptr ("test-repo" ),
1550+ Description : github .Ptr ("Test repository" ),
1551+ Private : github .Ptr (true ),
1552+ HTMLURL : github .Ptr ("https://github.com/testuser/test-repo" ),
1553+ CloneURL : github .Ptr ("https://github.com/testuser/test-repo.git" ),
1554+ CreatedAt : & github.Timestamp {Time : time .Now ()},
1555+ Owner : & github.User {
1556+ Login : github .Ptr ("testuser" ),
1557+ },
1558+ }
1559+
1560+ tests := []struct {
1561+ name string
1562+ mockedClient * http.Client
1563+ requestArgs map [string ]interface {}
1564+ expectError bool
1565+ expectedRepo * github.Repository
1566+ expectedErrMsg string
1567+ }{
1568+ {
1569+ name : "successful repository creation from template with all params" ,
1570+ mockedClient : mock .NewMockedHTTPClient (
1571+ mock .WithRequestMatchHandler (
1572+ mock.EndpointPattern {
1573+ Pattern : "/repos/template-owner/template-repo/generate" ,
1574+ Method : "POST" ,
1575+ },
1576+ expectRequestBody (t , map [string ]interface {}{
1577+ "name" : "test-repo" ,
1578+ "description" : "Test repository" ,
1579+ "private" : true ,
1580+ "include_all_branches" : true ,
1581+ }).andThen (
1582+ mockResponse (t , http .StatusCreated , mockRepo ),
1583+ ),
1584+ ),
1585+ ),
1586+ requestArgs : map [string ]interface {}{
1587+ "name" : "test-repo" ,
1588+ "description" : "Test repository" ,
1589+ "private" : true ,
1590+ "includeAllBranches" : true ,
1591+ "templateOwner" : "template-owner" ,
1592+ "templateRepo" : "template-repo" ,
1593+ },
1594+ expectError : false ,
1595+ expectedRepo : mockRepo ,
1596+ },
1597+ {
1598+ name : "successful repository creation from template with minimal params" ,
1599+ mockedClient : mock .NewMockedHTTPClient (
1600+ mock .WithRequestMatchHandler (
1601+ mock.EndpointPattern {
1602+ Pattern : "/repos/template-owner/template-repo/generate" ,
1603+ Method : "POST" ,
1604+ },
1605+ expectRequestBody (t , map [string ]interface {}{
1606+ "name" : "test-repo" ,
1607+ "description" : "" ,
1608+ "private" : false ,
1609+ "include_all_branches" : false ,
1610+ }).andThen (
1611+ mockResponse (t , http .StatusCreated , mockRepo ),
1612+ ),
1613+ ),
1614+ ),
1615+ requestArgs : map [string ]interface {}{
1616+ "name" : "test-repo" ,
1617+ "templateOwner" : "template-owner" ,
1618+ "templateRepo" : "template-repo" ,
1619+ },
1620+ expectError : false ,
1621+ expectedRepo : mockRepo ,
1622+ },
1623+ {
1624+ name : "repository creation from template fails" ,
1625+ mockedClient : mock .NewMockedHTTPClient (
1626+ mock .WithRequestMatchHandler (
1627+ mock.EndpointPattern {
1628+ Pattern : "/repos/template-owner/template-repo/generate" ,
1629+ Method : "POST" ,
1630+ },
1631+ http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
1632+ w .WriteHeader (http .StatusUnprocessableEntity )
1633+ _ , _ = w .Write ([]byte (`{"message": "Repository creation from template failed"}` ))
1634+ }),
1635+ ),
1636+ ),
1637+ requestArgs : map [string ]interface {}{
1638+ "name" : "invalid-repo" ,
1639+ "templateOwner" : "template-owner" ,
1640+ "templateRepo" : "template-repo" ,
1641+ },
1642+ expectError : true ,
1643+ expectedErrMsg : "failed to create repository from template" ,
1644+ },
1645+ }
1646+
1647+ for _ , tc := range tests {
1648+ t .Run (tc .name , func (t * testing.T ) {
1649+ // Setup client with mock
1650+ client := github .NewClient (tc .mockedClient )
1651+ _ , handler := CreateRepositoryFromTemplate (stubGetClientFn (client ), translations .NullTranslationHelper )
1652+
1653+ // Create call request
1654+ request := createMCPRequest (tc .requestArgs )
1655+
1656+ // Call handler
1657+ result , err := handler (context .Background (), request )
1658+
1659+ // Verify results
1660+ if tc .expectError {
1661+ require .Error (t , err )
1662+ assert .Contains (t , err .Error (), tc .expectedErrMsg )
1663+ return
1664+ }
1665+
1666+ require .NoError (t , err )
1667+
1668+ // Parse the result and get the text content if no error
1669+ textContent := getTextResult (t , result )
1670+
1671+ // Unmarshal and verify the result
1672+ var returnedRepo github.Repository
1673+ err = json .Unmarshal ([]byte (textContent .Text ), & returnedRepo )
1674+ assert .NoError (t , err )
1675+
1676+ // Verify repository details
1677+ assert .Equal (t , * tc .expectedRepo .Name , * returnedRepo .Name )
1678+ assert .Equal (t , * tc .expectedRepo .Description , * returnedRepo .Description )
1679+ assert .Equal (t , * tc .expectedRepo .Private , * returnedRepo .Private )
1680+ assert .Equal (t , * tc .expectedRepo .HTMLURL , * returnedRepo .HTMLURL )
1681+ assert .Equal (t , * tc .expectedRepo .Owner .Login , * returnedRepo .Owner .Login )
1682+ })
1683+ }
1684+ }
0 commit comments