@@ -163,9 +163,187 @@ func Test_SearchRepositories(t *testing.T) {
163163 assert .Equal (t , * tc .expectedResult .Repositories [i ].FullName , repo .FullName )
164164 assert .Equal (t , * tc .expectedResult .Repositories [i ].HTMLURL , repo .HTMLURL )
165165 }
166+ })
167+ }
168+ }
169+
170+ func Test_SearchRepositories_IFC_InsidersMode (t * testing.T ) {
171+ t .Parallel ()
166172
173+ serverTool := SearchRepositories (translations .NullTranslationHelper )
174+
175+ type repoFixture struct {
176+ owner string
177+ name string
178+ isPrivate bool
179+ collaborators []string
180+ collaboratorsStatus int
181+ }
182+
183+ makeRepo := func (r repoFixture ) * github.Repository {
184+ return & github.Repository {
185+ ID : github .Ptr (int64 (1 )),
186+ Name : github .Ptr (r .name ),
187+ FullName : github .Ptr (r .owner + "/" + r .name ),
188+ Private : github .Ptr (r .isPrivate ),
189+ Owner : & github.User {Login : github .Ptr (r .owner )},
190+ }
191+ }
192+
193+ makeMockClient := func (repos []repoFixture ) * http.Client {
194+ searchResult := & github.RepositoriesSearchResult {
195+ Total : github .Ptr (len (repos )),
196+ IncompleteResults : github .Ptr (false ),
197+ }
198+ for _ , r := range repos {
199+ searchResult .Repositories = append (searchResult .Repositories , makeRepo (r ))
200+ }
201+
202+ collaboratorsByPath := map [string ]repoFixture {}
203+ for _ , r := range repos {
204+ collaboratorsByPath ["/repos/" + r .owner + "/" + r .name + "/collaborators" ] = r
205+ }
206+
207+ return MockHTTPClientWithHandlers (map [string ]http.HandlerFunc {
208+ GetSearchRepositories : mockResponse (t , http .StatusOK , searchResult ),
209+ GetReposCollaboratorsByOwnerByRepo : func (w http.ResponseWriter , req * http.Request ) {
210+ r , ok := collaboratorsByPath [req .URL .Path ]
211+ if ! ok {
212+ w .WriteHeader (http .StatusOK )
213+ _ , _ = w .Write ([]byte ("[]" ))
214+ return
215+ }
216+ if r .collaboratorsStatus != 0 && r .collaboratorsStatus != http .StatusOK {
217+ w .WriteHeader (r .collaboratorsStatus )
218+ return
219+ }
220+ users := make ([]* github.User , len (r .collaborators ))
221+ for i , login := range r .collaborators {
222+ users [i ] = & github.User {Login : github .Ptr (login )}
223+ }
224+ body , _ := json .Marshal (users )
225+ w .WriteHeader (http .StatusOK )
226+ _ , _ = w .Write (body )
227+ },
167228 })
168229 }
230+
231+ reqParams := map [string ]any {"query" : "octocat" }
232+
233+ t .Run ("insiders mode disabled omits ifc label" , func (t * testing.T ) {
234+ deps := BaseDeps {
235+ Client : github .NewClient (makeMockClient ([]repoFixture {{owner : "octocat" , name : "public-repo" }})),
236+ Flags : FeatureFlags {InsidersMode : false },
237+ }
238+ handler := serverTool .Handler (deps )
239+
240+ request := createMCPRequest (reqParams )
241+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
242+ require .NoError (t , err )
243+ require .False (t , result .IsError )
244+ assert .Nil (t , result .Meta )
245+ })
246+
247+ t .Run ("insiders mode all public emits public untrusted" , func (t * testing.T ) {
248+ deps := BaseDeps {
249+ Client : github .NewClient (makeMockClient ([]repoFixture {
250+ {owner : "octocat" , name : "public-a" },
251+ {owner : "octocat" , name : "public-b" },
252+ })),
253+ Flags : FeatureFlags {InsidersMode : true },
254+ }
255+ handler := serverTool .Handler (deps )
256+
257+ request := createMCPRequest (reqParams )
258+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
259+ require .NoError (t , err )
260+ require .False (t , result .IsError )
261+
262+ require .NotNil (t , result .Meta )
263+ ifcMap := unmarshalIFC (t , result .Meta ["ifc" ])
264+ assert .Equal (t , "untrusted" , ifcMap ["integrity" ])
265+ assert .Equal (t , []any {"public" }, ifcMap ["confidentiality" ])
266+ })
267+
268+ t .Run ("insiders mode mixed public and private keeps the private readers" , func (t * testing.T ) {
269+ deps := BaseDeps {
270+ Client : github .NewClient (makeMockClient ([]repoFixture {
271+ {owner : "octocat" , name : "private-repo" , isPrivate : true , collaborators : []string {"alice" }},
272+ {owner : "octocat" , name : "public-repo" },
273+ })),
274+ Flags : FeatureFlags {InsidersMode : true },
275+ }
276+ handler := serverTool .Handler (deps )
277+
278+ request := createMCPRequest (reqParams )
279+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
280+ require .NoError (t , err )
281+ require .False (t , result .IsError )
282+
283+ require .NotNil (t , result .Meta )
284+ ifcMap := unmarshalIFC (t , result .Meta ["ifc" ])
285+ assert .Equal (t , "untrusted" , ifcMap ["integrity" ])
286+ assert .Equal (t , []any {"alice" }, ifcMap ["confidentiality" ])
287+ })
288+
289+ t .Run ("insiders mode two private repos intersect collaborators" , func (t * testing.T ) {
290+ deps := BaseDeps {
291+ Client : github .NewClient (makeMockClient ([]repoFixture {
292+ {owner : "octocat" , name : "repo-a" , isPrivate : true , collaborators : []string {"alice" , "bob" , "carol" }},
293+ {owner : "octocat" , name : "repo-b" , isPrivate : true , collaborators : []string {"bob" , "carol" , "dan" }},
294+ })),
295+ Flags : FeatureFlags {InsidersMode : true },
296+ }
297+ handler := serverTool .Handler (deps )
298+
299+ request := createMCPRequest (reqParams )
300+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
301+ require .NoError (t , err )
302+ require .False (t , result .IsError )
303+
304+ require .NotNil (t , result .Meta )
305+ ifcMap := unmarshalIFC (t , result .Meta ["ifc" ])
306+ assert .Equal (t , "untrusted" , ifcMap ["integrity" ])
307+ assert .Equal (t , []any {"bob" , "carol" }, ifcMap ["confidentiality" ])
308+ })
309+
310+ t .Run ("insiders mode skips ifc label when collaborators lookup fails" , func (t * testing.T ) {
311+ deps := BaseDeps {
312+ Client : github .NewClient (makeMockClient ([]repoFixture {
313+ {owner : "octocat" , name : "private-repo" , isPrivate : true , collaboratorsStatus : http .StatusInternalServerError },
314+ })),
315+ Flags : FeatureFlags {InsidersMode : true },
316+ }
317+ handler := serverTool .Handler (deps )
318+
319+ request := createMCPRequest (reqParams )
320+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
321+ require .NoError (t , err )
322+ require .False (t , result .IsError , "tool call should still succeed when collaborators lookup fails" )
323+
324+ if result .Meta != nil {
325+ _ , hasIFC := result .Meta ["ifc" ]
326+ assert .False (t , hasIFC , "ifc label should be omitted when collaborators lookup fails" )
327+ }
328+ })
329+
330+ t .Run ("insiders mode empty results emits public untrusted" , func (t * testing.T ) {
331+ deps := BaseDeps {
332+ Client : github .NewClient (makeMockClient (nil )),
333+ Flags : FeatureFlags {InsidersMode : true },
334+ }
335+ handler := serverTool .Handler (deps )
336+
337+ request := createMCPRequest (reqParams )
338+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
339+ require .NoError (t , err )
340+ require .False (t , result .IsError )
341+
342+ require .NotNil (t , result .Meta )
343+ ifcMap := unmarshalIFC (t , result .Meta ["ifc" ])
344+ assert .Equal (t , "untrusted" , ifcMap ["integrity" ])
345+ assert .Equal (t , []any {"public" }, ifcMap ["confidentiality" ])
346+ })
169347}
170348
171349func Test_SearchRepositories_FullOutput (t * testing.T ) {
0 commit comments