@@ -24,16 +24,6 @@ import (
24
24
"github.com/stretchr/testify/require"
25
25
)
26
26
27
- // Should be set to opt-in to tests that mutate global state
28
- const E2EGlobalMutationOptInEnv = "GITHUB_MCP_SERVER_E2E_MUTATE_GLOBAL_STATE"
29
-
30
- // skipIfGlobalMutationNotOptedIn skips the test if the opt-in env var is not set
31
- func skipIfGlobalMutationNotOptedIn (t * testing.T ) {
32
- if os .Getenv (E2EGlobalMutationOptInEnv ) == "" {
33
- t .Skipf ("Skipping test: set %s=1 to opt-in to global state mutation tests" , E2EGlobalMutationOptInEnv )
34
- }
35
- }
36
-
37
27
var (
38
28
// Shared variables and sync.Once instances to ensure one-time execution
39
29
getTokenOnce sync.Once
@@ -1559,280 +1549,3 @@ func TestListNotifications(t *testing.T) {
1559
1549
err = json .Unmarshal ([]byte (textContent .Text ), & notifications )
1560
1550
require .NoError (t , err , "expected to unmarshal text content successfully" )
1561
1551
}
1562
-
1563
- func TestManageNotificationSubscription (t * testing.T ) {
1564
- skipIfGlobalMutationNotOptedIn (t )
1565
- t .Parallel ()
1566
- client := setupMCPClient (t )
1567
- ctx := context .Background ()
1568
-
1569
- // List notifications to get a valid notificationID
1570
- listReq := mcp.CallToolRequest {}
1571
- listReq .Params .Name = "list_notifications"
1572
- listReq .Params .Arguments = map [string ]any {}
1573
- resp , err := client .CallTool (ctx , listReq )
1574
- require .NoError (t , err )
1575
- require .False (t , resp .IsError )
1576
-
1577
- textContent , ok := resp .Content [0 ].(mcp.TextContent )
1578
- require .True (t , ok )
1579
- var notifications []struct {
1580
- ID string `json:"id"`
1581
- }
1582
- err = json .Unmarshal ([]byte (textContent .Text ), & notifications )
1583
- require .NoError (t , err )
1584
- require .NotEmpty (t , notifications )
1585
- if len (notifications ) == 0 {
1586
- t .Skip ("No notifications available to test subscription management" )
1587
- }
1588
- notificationID := notifications [0 ].ID
1589
-
1590
- // Ignore notification
1591
- ignoreReq := mcp.CallToolRequest {}
1592
- ignoreReq .Params .Name = "manage_notification_subscription"
1593
- ignoreReq .Params .Arguments = map [string ]any {
1594
- "notificationID" : notificationID ,
1595
- "action" : "ignore" ,
1596
- }
1597
- resp , err = client .CallTool (ctx , ignoreReq )
1598
- require .NoError (t , err )
1599
- require .False (t , resp .IsError )
1600
- textContent , ok = resp .Content [0 ].(mcp.TextContent )
1601
- require .True (t , ok )
1602
- require .Contains (t , textContent .Text , "ignored" )
1603
-
1604
- // Validate with REST client
1605
- restClient := getRESTClient (t )
1606
- sub , _ , err := restClient .Activity .GetThreadSubscription (ctx , notificationID )
1607
- require .NoError (t , err )
1608
- require .NotNil (t , sub )
1609
- require .True (t , sub .GetIgnored (), "expected notification subscription to be ignored" )
1610
-
1611
- // Watch notification
1612
- watchReq := mcp.CallToolRequest {}
1613
- watchReq .Params .Name = "manage_notification_subscription"
1614
- watchReq .Params .Arguments = map [string ]any {
1615
- "notificationID" : notificationID ,
1616
- "action" : "watch" ,
1617
- }
1618
- resp , err = client .CallTool (ctx , watchReq )
1619
- require .NoError (t , err )
1620
- require .False (t , resp .IsError )
1621
- textContent , ok = resp .Content [0 ].(mcp.TextContent )
1622
- require .True (t , ok )
1623
- require .Contains (t , textContent .Text , "subscribed" )
1624
-
1625
- // Validate with REST client
1626
- sub , _ , err = restClient .Activity .GetThreadSubscription (ctx , notificationID )
1627
- require .NoError (t , err )
1628
- require .NotNil (t , sub )
1629
- require .False (t , sub .GetIgnored (), "expected notification subscription to not be ignored (watch)" )
1630
- require .True (t , sub .GetSubscribed (), "expected notification subscription to be subscribed" )
1631
-
1632
- // Delete notification subscription
1633
- deleteReq := mcp.CallToolRequest {}
1634
- deleteReq .Params .Name = "manage_notification_subscription"
1635
- deleteReq .Params .Arguments = map [string ]any {
1636
- "notificationID" : notificationID ,
1637
- "action" : "delete" ,
1638
- }
1639
- resp , err = client .CallTool (ctx , deleteReq )
1640
- require .NoError (t , err )
1641
- require .False (t , resp .IsError )
1642
- textContent , ok = resp .Content [0 ].(mcp.TextContent )
1643
- require .True (t , ok )
1644
- require .Contains (t , textContent .Text , "deleted" )
1645
-
1646
- // Validate with REST client
1647
- sub , resp2 , err := restClient .Activity .GetThreadSubscription (ctx , notificationID )
1648
- require .NoError (t , err )
1649
- require .NotNil (t , sub )
1650
- require .False (t , sub .GetSubscribed ())
1651
- require .True (t , sub .GetIgnored ())
1652
- require .Equal (t , 204 , resp2 .StatusCode )
1653
- }
1654
-
1655
- func TestManageRepositoryNotificationSubscription (t * testing.T ) {
1656
- skipIfGlobalMutationNotOptedIn (t )
1657
- t .Parallel ()
1658
- client := setupMCPClient (t )
1659
- ctx := context .Background ()
1660
-
1661
- // Use a well-known repo for the test (e.g., the user's own repo)
1662
- owner := "github"
1663
- repo := "github-mcp-server"
1664
-
1665
- // Ignore repo notifications
1666
- ignoreReq := mcp.CallToolRequest {}
1667
- ignoreReq .Params .Name = "manage_repository_notification_subscription"
1668
- ignoreReq .Params .Arguments = map [string ]any {
1669
- "owner" : owner ,
1670
- "repo" : repo ,
1671
- "action" : "ignore" ,
1672
- }
1673
- resp , err := client .CallTool (ctx , ignoreReq )
1674
- require .NoError (t , err )
1675
- require .False (t , resp .IsError )
1676
- textContent , ok := resp .Content [0 ].(mcp.TextContent )
1677
- require .True (t , ok )
1678
- require .Contains (t , textContent .Text , "ignored" )
1679
-
1680
- // Validate with REST client
1681
- restClient := getRESTClient (t )
1682
- sub , _ , err := restClient .Activity .GetRepositorySubscription (ctx , owner , repo )
1683
- require .NoError (t , err )
1684
- require .NotNil (t , sub )
1685
- require .True (t , sub .GetIgnored (), "expected repository subscription to be ignored" )
1686
-
1687
- // Watch repo notifications
1688
- watchReq := mcp.CallToolRequest {}
1689
- watchReq .Params .Name = "manage_repository_notification_subscription"
1690
- watchReq .Params .Arguments = map [string ]any {
1691
- "owner" : owner ,
1692
- "repo" : repo ,
1693
- "action" : "watch" ,
1694
- }
1695
- resp , err = client .CallTool (ctx , watchReq )
1696
- require .NoError (t , err )
1697
- require .False (t , resp .IsError )
1698
- textContent , ok = resp .Content [0 ].(mcp.TextContent )
1699
- require .True (t , ok )
1700
- require .Contains (t , textContent .Text , "subscribed" )
1701
-
1702
- // Validate with REST client
1703
- sub , _ , err = restClient .Activity .GetRepositorySubscription (ctx , owner , repo )
1704
- require .NoError (t , err )
1705
- require .NotNil (t , sub )
1706
- require .False (t , sub .GetIgnored (), "expected repository subscription to not be ignored (watch)" )
1707
- require .True (t , sub .GetSubscribed (), "expected repository subscription to be subscribed" )
1708
-
1709
- // Delete repo notification subscription
1710
- deleteReq := mcp.CallToolRequest {}
1711
- deleteReq .Params .Name = "manage_repository_notification_subscription"
1712
- deleteReq .Params .Arguments = map [string ]any {
1713
- "owner" : owner ,
1714
- "repo" : repo ,
1715
- "action" : "delete" ,
1716
- }
1717
- resp , err = client .CallTool (ctx , deleteReq )
1718
- require .NoError (t , err )
1719
- require .False (t , resp .IsError )
1720
- textContent , ok = resp .Content [0 ].(mcp.TextContent )
1721
- require .True (t , ok )
1722
- require .Contains (t , textContent .Text , "deleted" )
1723
-
1724
- // Validate with REST client
1725
- sub , resp2 , err := restClient .Activity .GetRepositorySubscription (ctx , owner , repo )
1726
- require .NoError (t , err )
1727
- require .NotNil (t , sub )
1728
- require .False (t , sub .GetSubscribed ())
1729
- require .True (t , sub .GetIgnored ())
1730
- require .Equal (t , 204 , resp2 .StatusCode )
1731
- }
1732
-
1733
- func TestDismissNotification (t * testing.T ) {
1734
- skipIfGlobalMutationNotOptedIn (t )
1735
- t .Parallel ()
1736
- client := setupMCPClient (t )
1737
- ctx := context .Background ()
1738
-
1739
- // List notifications to get a valid threadID
1740
- listReq := mcp.CallToolRequest {}
1741
- listReq .Params .Name = "list_notifications"
1742
- listReq .Params .Arguments = map [string ]any {}
1743
- resp , err := client .CallTool (ctx , listReq )
1744
- require .NoError (t , err )
1745
- require .False (t , resp .IsError )
1746
- textContent , ok := resp .Content [0 ].(mcp.TextContent )
1747
- require .True (t , ok )
1748
- var notifications []struct {
1749
- ID string `json:"id"`
1750
- }
1751
- err = json .Unmarshal ([]byte (textContent .Text ), & notifications )
1752
- require .NoError (t , err )
1753
- if len (notifications ) == 0 {
1754
- t .Skip ("No notifications available to test dismissal" )
1755
- }
1756
- require .NotEmpty (t , notifications )
1757
- threadID := notifications [0 ].ID
1758
-
1759
- // Dismiss notification (mark as read)
1760
- dismissReq := mcp.CallToolRequest {}
1761
- dismissReq .Params .Name = "dismiss_notification"
1762
- dismissReq .Params .Arguments = map [string ]any {
1763
- "threadID" : threadID ,
1764
- "state" : "read" ,
1765
- }
1766
- resp , err = client .CallTool (ctx , dismissReq )
1767
- require .NoError (t , err )
1768
- require .False (t , resp .IsError )
1769
- textContent , ok = resp .Content [0 ].(mcp.TextContent )
1770
- require .True (t , ok )
1771
- require .Contains (t , textContent .Text , "read" )
1772
- }
1773
-
1774
- func TestMarkAllNotificationsRead (t * testing.T ) {
1775
- skipIfGlobalMutationNotOptedIn (t )
1776
- t .Parallel ()
1777
- client := setupMCPClient (t )
1778
- ctx := context .Background ()
1779
-
1780
- // Limit to notifications updated within the last hour
1781
- oneHourAgo := nowMinusOneHourRFC3339 ()
1782
- markAllReq := mcp.CallToolRequest {}
1783
- markAllReq .Params .Name = "mark_all_notifications_read"
1784
- markAllReq .Params .Arguments = map [string ]any {
1785
- "since" : oneHourAgo ,
1786
- }
1787
- resp , err := client .CallTool (ctx , markAllReq )
1788
- require .NoError (t , err )
1789
- require .False (t , resp .IsError )
1790
- textContent , ok := resp .Content [0 ].(mcp.TextContent )
1791
- require .True (t , ok )
1792
- require .Contains (t , textContent .Text , "All notifications marked as read" )
1793
-
1794
- }
1795
-
1796
- // nowMinusOneHourRFC3339 returns the RFC3339 timestamp for one hour ago from now (UTC)
1797
- func nowMinusOneHourRFC3339 () string {
1798
- return time .Now ().UTC ().Add (- 1 * time .Hour ).Format (time .RFC3339 )
1799
- }
1800
-
1801
- func TestGetNotificationDetails (t * testing.T ) {
1802
- t .Parallel ()
1803
- client := setupMCPClient (t )
1804
- ctx := context .Background ()
1805
-
1806
- // List notifications to get a valid notificationID
1807
- listReq := mcp.CallToolRequest {}
1808
- listReq .Params .Name = "list_notifications"
1809
- listReq .Params .Arguments = map [string ]any {}
1810
- resp , err := client .CallTool (ctx , listReq )
1811
- require .NoError (t , err )
1812
- require .False (t , resp .IsError )
1813
- textContent , ok := resp .Content [0 ].(mcp.TextContent )
1814
- require .True (t , ok )
1815
- var notifications []struct {
1816
- ID string `json:"id"`
1817
- }
1818
- err = json .Unmarshal ([]byte (textContent .Text ), & notifications )
1819
- require .NoError (t , err )
1820
- require .NotEmpty (t , notifications )
1821
- if len (notifications ) == 0 {
1822
- t .Skip ("No notifications available to test dismissal" )
1823
- }
1824
- notificationID := notifications [0 ].ID
1825
-
1826
- // Get notification details
1827
- detailsReq := mcp.CallToolRequest {}
1828
- detailsReq .Params .Name = "get_notification_details"
1829
- detailsReq .Params .Arguments = map [string ]any {
1830
- "notificationID" : notificationID ,
1831
- }
1832
- resp , err = client .CallTool (ctx , detailsReq )
1833
- require .NoError (t , err )
1834
- require .False (t , resp .IsError )
1835
- textContent , ok = resp .Content [0 ].(mcp.TextContent )
1836
- require .True (t , ok )
1837
- require .Contains (t , textContent .Text , notificationID )
1838
- }
0 commit comments