@@ -6,13 +6,16 @@ import (
66 "errors"
77 "fmt"
88 "net/http"
9+ "testing"
910 "time"
1011
1112 "github.com/github/github-mcp-server/pkg/lockdown"
1213 "github.com/github/github-mcp-server/pkg/raw"
1314 "github.com/github/github-mcp-server/pkg/translations"
1415 "github.com/google/go-github/v79/github"
1516 "github.com/shurcooL/githubv4"
17+ "github.com/stretchr/testify/assert"
18+ "github.com/stretchr/testify/require"
1619)
1720
1821// stubDeps is a test helper that implements ToolDependencies with configurable behavior.
@@ -49,10 +52,12 @@ func (s stubDeps) GetRawClient(ctx context.Context) (*raw.Client, error) {
4952 return nil , nil
5053}
5154
52- func (s stubDeps ) GetRepoAccessCache () * lockdown.RepoAccessCache { return s .repoAccessCache }
53- func (s stubDeps ) GetT () translations.TranslationHelperFunc { return s .t }
54- func (s stubDeps ) GetFlags () FeatureFlags { return s .flags }
55- func (s stubDeps ) GetContentWindowSize () int { return s .contentWindowSize }
55+ func (s stubDeps ) GetRepoAccessCache (ctx context.Context ) (* lockdown.RepoAccessCache , error ) {
56+ return s .repoAccessCache , nil
57+ }
58+ func (s stubDeps ) GetT () translations.TranslationHelperFunc { return s .t }
59+ func (s stubDeps ) GetFlags () FeatureFlags { return s .flags }
60+ func (s stubDeps ) GetContentWindowSize () int { return s .contentWindowSize }
5661
5762// Helper functions to create stub client functions for error testing
5863func stubClientFnFromHTTP (httpClient * http.Client ) func (context.Context ) (* github.Client , error ) {
@@ -98,3 +103,108 @@ func badRequestHandler(msg string) http.HandlerFunc {
98103 http .Error (w , string (b ), http .StatusBadRequest )
99104 }
100105}
106+
107+ // TestNewMCPServer_CreatesSuccessfully verifies that the server can be created
108+ // with the deps injection middleware properly configured.
109+ func TestNewMCPServer_CreatesSuccessfully (t * testing.T ) {
110+ t .Parallel ()
111+
112+ // Create a minimal server configuration
113+ cfg := MCPServerConfig {
114+ Version : "test" ,
115+ Host : "" , // defaults to github.com
116+ Token : "test-token" ,
117+ EnabledToolsets : []string {"context" },
118+ ReadOnly : false ,
119+ Translator : translations .NullTranslationHelper ,
120+ ContentWindowSize : 5000 ,
121+ LockdownMode : false ,
122+ }
123+
124+ deps := stubDeps {}
125+
126+ // Create the server
127+ server , err := NewMCPServer (& cfg , deps )
128+ require .NoError (t , err , "expected server creation to succeed" )
129+ require .NotNil (t , server , "expected server to be non-nil" )
130+
131+ // The fact that the server was created successfully indicates that:
132+ // 1. The deps injection middleware is properly added
133+ // 2. Tools can be registered without panicking
134+ //
135+ // If the middleware wasn't properly added, tool calls would panic with
136+ // "ToolDependencies not found in context" when executed.
137+ //
138+ // The actual middleware functionality and tool execution with ContextWithDeps
139+ // is already tested in pkg/github/*_test.go.
140+ }
141+
142+ // TestResolveEnabledToolsets verifies the toolset resolution logic.
143+ func TestResolveEnabledToolsets (t * testing.T ) {
144+ t .Parallel ()
145+
146+ tests := []struct {
147+ name string
148+ cfg MCPServerConfig
149+ expectedResult []string
150+ }{
151+ {
152+ name : "nil toolsets without dynamic mode and no tools - use defaults" ,
153+ cfg : MCPServerConfig {
154+ EnabledToolsets : nil ,
155+ DynamicToolsets : false ,
156+ EnabledTools : nil ,
157+ },
158+ expectedResult : nil , // nil means "use defaults"
159+ },
160+ {
161+ name : "nil toolsets with dynamic mode - start empty" ,
162+ cfg : MCPServerConfig {
163+ EnabledToolsets : nil ,
164+ DynamicToolsets : true ,
165+ EnabledTools : nil ,
166+ },
167+ expectedResult : []string {}, // empty slice means no toolsets
168+ },
169+ {
170+ name : "explicit toolsets" ,
171+ cfg : MCPServerConfig {
172+ EnabledToolsets : []string {"repos" , "issues" },
173+ DynamicToolsets : false ,
174+ },
175+ expectedResult : []string {"repos" , "issues" },
176+ },
177+ {
178+ name : "empty toolsets - disable all" ,
179+ cfg : MCPServerConfig {
180+ EnabledToolsets : []string {},
181+ DynamicToolsets : false ,
182+ },
183+ expectedResult : []string {}, // empty slice means no toolsets
184+ },
185+ {
186+ name : "specific tools without toolsets - no default toolsets" ,
187+ cfg : MCPServerConfig {
188+ EnabledToolsets : nil ,
189+ DynamicToolsets : false ,
190+ EnabledTools : []string {"get_me" },
191+ },
192+ expectedResult : []string {}, // empty slice when tools specified but no toolsets
193+ },
194+ {
195+ name : "dynamic mode with explicit toolsets removes all and default" ,
196+ cfg : MCPServerConfig {
197+ EnabledToolsets : []string {"all" , "repos" },
198+ DynamicToolsets : true ,
199+ },
200+ expectedResult : []string {"repos" }, // "all" is removed in dynamic mode
201+ },
202+ }
203+
204+ for _ , tc := range tests {
205+ t .Run (tc .name , func (t * testing.T ) {
206+ result := resolveEnabledToolsets (& tc .cfg )
207+ assert .Equal (t , tc .expectedResult , result )
208+ })
209+ }
210+ }
0 commit comments