11package github
22
33import (
4+ "bytes"
45 "context"
56 "encoding/json"
67 "fmt"
8+ "io"
79 "net/http"
810 "strings"
911 "testing"
@@ -20,9 +22,103 @@ import (
2022 "github.com/stretchr/testify/require"
2123)
2224
23- var defaultGQLClient * githubv4.Client = githubv4 .NewClient (githubv4mock . NewMockedHTTPClient ())
25+ var defaultGQLClient * githubv4.Client = githubv4 .NewClient (newRepoAccessHTTPClient ())
2426var repoAccessCache * lockdown.RepoAccessCache = stubRepoAccessCache (defaultGQLClient , 15 * time .Minute )
2527
28+ type repoAccessKey struct {
29+ owner string
30+ repo string
31+ username string
32+ }
33+
34+ type repoAccessValue struct {
35+ isPrivate bool
36+ permission string
37+ }
38+
39+ type repoAccessMockTransport struct {
40+ responses map [repoAccessKey ]repoAccessValue
41+ }
42+
43+ func newRepoAccessHTTPClient () * http.Client {
44+ responses := map [repoAccessKey ]repoAccessValue {
45+ {owner : "owner2" , repo : "repo2" , username : "testuser2" }: {isPrivate : true },
46+ {owner : "owner" , repo : "repo" , username : "testuser" }: {isPrivate : false , permission : "READ" },
47+ }
48+
49+ return & http.Client {Transport : & repoAccessMockTransport {responses : responses }}
50+ }
51+
52+ func (rt * repoAccessMockTransport ) RoundTrip (req * http.Request ) (* http.Response , error ) {
53+ if req .Body == nil {
54+ return nil , fmt .Errorf ("missing request body" )
55+ }
56+
57+ var payload struct {
58+ Query string `json:"query"`
59+ Variables map [string ]any `json:"variables"`
60+ }
61+
62+ if err := json .NewDecoder (req .Body ).Decode (& payload ); err != nil {
63+ return nil , err
64+ }
65+ _ = req .Body .Close ()
66+
67+ owner := toString (payload .Variables ["owner" ])
68+ repo := toString (payload .Variables ["name" ])
69+ username := toString (payload .Variables ["username" ])
70+
71+ value , ok := rt .responses [repoAccessKey {owner : owner , repo : repo , username : username }]
72+ if ! ok {
73+ value = repoAccessValue {isPrivate : false , permission : "WRITE" }
74+ }
75+
76+ edges := []any {}
77+ if value .permission != "" {
78+ edges = append (edges , map [string ]any {
79+ "permission" : value .permission ,
80+ "node" : map [string ]any {
81+ "login" : username ,
82+ },
83+ })
84+ }
85+
86+ responseBody , err := json .Marshal (map [string ]any {
87+ "data" : map [string ]any {
88+ "repository" : map [string ]any {
89+ "isPrivate" : value .isPrivate ,
90+ "collaborators" : map [string ]any {
91+ "edges" : edges ,
92+ },
93+ },
94+ },
95+ })
96+ if err != nil {
97+ return nil , err
98+ }
99+
100+ resp := & http.Response {
101+ StatusCode : http .StatusOK ,
102+ Header : make (http.Header ),
103+ Body : io .NopCloser (bytes .NewReader (responseBody )),
104+ }
105+ resp .Header .Set ("Content-Type" , "application/json" )
106+ return resp , nil
107+ }
108+
109+ func toString (v any ) string {
110+ switch value := v .(type ) {
111+ case string :
112+ return value
113+ case fmt.Stringer :
114+ return value .String ()
115+ case nil :
116+ return ""
117+ default :
118+ return fmt .Sprintf ("%v" , value )
119+ }
120+ }
121+
26122func Test_GetIssue (t * testing.T ) {
27123 // Verify tool definition once
28124 mockClient := github .NewClient (nil )
@@ -55,6 +151,22 @@ func Test_GetIssue(t *testing.T) {
55151 },
56152 },
57153 }
154+ mockIssue2 := & github.Issue {
155+ Number : github .Ptr (422 ),
156+ Title : github .Ptr ("Test Issue 2" ),
157+ Body : github .Ptr ("This is a test issue 2" ),
158+ State : github .Ptr ("open" ),
159+ HTMLURL : github .Ptr ("https://github.com/owner/repo/issues/42" ),
160+ User : & github.User {
161+ Login : github .Ptr ("testuser2" ),
162+ },
163+ Repository : & github.Repository {
164+ Name : github .Ptr ("repo2" ),
165+ Owner : & github.User {
166+ Login : github .Ptr ("owner2" ),
167+ },
168+ },
169+ }
58170
59171 tests := []struct {
60172 name string
@@ -77,8 +189,8 @@ func Test_GetIssue(t *testing.T) {
77189 ),
78190 requestArgs : map [string ]interface {}{
79191 "method" : "get" ,
80- "owner" : "owner " ,
81- "repo" : "repo " ,
192+ "owner" : "owner2 " ,
193+ "repo" : "repo2 " ,
82194 "issue_number" : float64 (42 ),
83195 },
84196 expectedIssue : mockIssue ,
@@ -105,7 +217,7 @@ func Test_GetIssue(t *testing.T) {
105217 mockedClient : mock .NewMockedHTTPClient (
106218 mock .WithRequestMatch (
107219 mock .GetReposIssuesByOwnerByRepoByIssueNumber ,
108- mockIssue ,
220+ mockIssue2 ,
109221 ),
110222 ),
111223 gqlHTTPClient : githubv4mock .NewMockedHTTPClient (
@@ -124,9 +236,9 @@ func Test_GetIssue(t *testing.T) {
124236 } `graphql:"repository(owner: $owner, name: $name)"`
125237 }{},
126238 map [string ]any {
127- "owner" : githubv4 .String ("owner " ),
128- "name" : githubv4 .String ("repo " ),
129- "username" : githubv4 .String ("testuser " ),
239+ "owner" : githubv4 .String ("owner2 " ),
240+ "name" : githubv4 .String ("repo2 " ),
241+ "username" : githubv4 .String ("testuser2 " ),
130242 },
131243 githubv4mock .DataResponse (map [string ]any {
132244 "repository" : map [string ]any {
@@ -140,11 +252,11 @@ func Test_GetIssue(t *testing.T) {
140252 ),
141253 requestArgs : map [string ]interface {}{
142254 "method" : "get" ,
143- "owner" : "owner " ,
144- "repo" : "repo " ,
145- "issue_number" : float64 (42 ),
255+ "owner" : "owner2 " ,
256+ "repo" : "repo2 " ,
257+ "issue_number" : float64 (422 ),
146258 },
147- expectedIssue : mockIssue ,
259+ expectedIssue : mockIssue2 ,
148260 lockdownEnabled : true ,
149261 },
150262 {
0 commit comments