@@ -97,11 +97,17 @@ def test_get_issues_for_pr_success(monkeypatch):
9797 _patch_action_inputs (monkeypatch )
9898 _patch_issues_template (monkeypatch )
9999
100- captured = {}
101- class Resp :
102- def raise_for_status (self ): pass
103- def json (self ):
104- return {
100+ class MockRequester :
101+ def __init__ (self ):
102+ self .called = False
103+ self .last_query = None
104+ self .last_headers = None
105+ def graphql_query (self , query , headers ):
106+ self .called = True
107+ self .last_query = query
108+ self .last_headers = headers
109+ # Return (headers, payload) as expected by the new implementation
110+ return headers , {
105111 "data" : {
106112 "repository" : {
107113 "pullRequest" : {
@@ -113,34 +119,21 @@ def json(self):
113119 }
114120 }
115121
116- def fake_post (url , json = None , headers = None , verify = None , timeout = None ):
117- captured ["url" ] = url
118- captured ["json" ] = json
119- captured ["headers" ] = headers
120- captured ["verify" ] = verify
121- captured ["timeout" ] = timeout
122- return Resp ()
123-
124- monkeypatch .setattr (pru .requests , "post" , fake_post )
125-
126- result = pru .get_issues_for_pr (123 )
122+ requester = MockRequester ()
123+ result = pru .get_issues_for_pr (123 , requester )
127124 assert result == {'OWN/REPO#11' , 'OWN/REPO#22' }
128- assert captured ["url" ] == "https://api.github.com/graphql"
129- # Query string correctly formatted
130- assert captured ["json" ]["query" ] == "Q 123 OWN REPO 10"
131- # Headers include token
132- assert captured ["headers" ]["Authorization" ] == "Bearer TOK"
133- assert captured ["verify" ] is False
134- assert captured ["timeout" ] == 10
125+ assert requester .called
126+ assert requester .last_query == "Q 123 OWN REPO 10"
127+ assert requester .last_headers ["Authorization" ] == "Bearer TOK"
128+ assert requester .last_headers ["Content-Type" ] == "application/json"
135129
136130def test_get_issues_for_pr_empty_nodes (monkeypatch ):
137131 _patch_action_inputs (monkeypatch )
138132 _patch_issues_template (monkeypatch )
139133
140- class Resp :
141- def raise_for_status (self ): pass
142- def json (self ):
143- return {
134+ class MockRequester :
135+ def graphql_query (self , query , headers ):
136+ return headers , {
144137 "data" : {
145138 "repository" : {
146139 "pullRequest" : {
@@ -150,48 +143,49 @@ def json(self):
150143 }
151144 }
152145
153- monkeypatch . setattr ( pru . requests , "post" , lambda * a , ** k : Resp () )
154- assert pru .get_issues_for_pr (5 ) == set ()
146+ requester = MockRequester ( )
147+ assert pru .get_issues_for_pr (5 , requester ) == set ()
155148
156149def test_get_issues_for_pr_http_error (monkeypatch ):
157150 _patch_action_inputs (monkeypatch )
158151 _patch_issues_template (monkeypatch )
159152
160- class Resp :
161- def raise_for_status ( self ):
162- raise requests . HTTPError ( "Boom" )
163- def json ( self ):
164- return {}
153+ from github import GithubException
154+ class MockGithubException ( GithubException ):
155+ def __init__ ( self , status , data ):
156+ super (). __init__ ( status , data )
157+ # Do not set self.status or self.data directly
165158
166- monkeypatch .setattr (pru .requests , "post" , lambda * a , ** k : Resp ())
159+ class MockRequester :
160+ def graphql_query (self , query , headers ):
161+ raise MockGithubException (500 , "Boom" )
167162
168- with pytest .raises (requests .HTTPError ):
169- pru .get_issues_for_pr (77 )
163+ requester = MockRequester ()
164+ with pytest .raises (RuntimeError ) as excinfo :
165+ pru .get_issues_for_pr (77 , requester )
166+ assert "GitHub HTTP error 500" in str (excinfo .value )
170167
171168def test_get_issues_for_pr_malformed_response (monkeypatch ):
172169 _patch_action_inputs (monkeypatch )
173170 _patch_issues_template (monkeypatch )
174171
175- class Resp :
176- def raise_for_status (self ): pass
177- def json (self ):
178- # Missing the expected nested keys -> triggers KeyError
179- return {"data" : {}}
180-
181- monkeypatch .setattr (pru .requests , "post" , lambda * a , ** k : Resp ())
172+ class MockRequester :
173+ def graphql_query (self , query , headers ):
174+ return headers , {"data" : {}} # Missing nested keys
182175
176+ requester = MockRequester ()
183177 with pytest .raises (KeyError ):
184- pru .get_issues_for_pr (42 )
178+ pru .get_issues_for_pr (42 , requester )
185179
186180def test_get_issues_for_pr_caching (monkeypatch ):
187181 _patch_action_inputs (monkeypatch )
188182 _patch_issues_template (monkeypatch )
189183
190184 calls = {"count" : 0 }
191- class Resp :
192- def raise_for_status (self ): pass
193- def json ( self ):
194- return {
185+ class MockRequester :
186+ def graphql_query (self , query , headers ):
187+ calls [ "count" ] += 1
188+ return headers , {
195189 "data" : {
196190 "repository" : {
197191 "pullRequest" : {
@@ -201,14 +195,9 @@ def json(self):
201195 }
202196 }
203197
204- def fake_post (* a , ** k ):
205- calls ["count" ] += 1
206- return Resp ()
207-
208- monkeypatch .setattr (pru .requests , "post" , fake_post )
209-
210- first = pru .get_issues_for_pr (900 )
211- second = pru .get_issues_for_pr (900 ) # should use cache
198+ requester = MockRequester ()
199+ first = pru .get_issues_for_pr (900 , requester )
200+ second = pru .get_issues_for_pr (900 , requester ) # should use cache
212201 assert first == {'OWN/REPO#9' } and second == {'OWN/REPO#9' }
213202 assert calls ["count" ] == 1 # only one network call
214203
@@ -217,30 +206,24 @@ def test_get_issues_for_pr_different_numbers_not_cached(monkeypatch):
217206 _patch_issues_template (monkeypatch )
218207
219208 calls = {"nums" : []}
220- class Resp :
221- def __init__ (self , n ): self .n = n
222- def raise_for_status (self ): pass
223- def json (self ):
224- return {
209+ class MockRequester :
210+ def graphql_query (self , query , headers ):
211+ # Extract pull number back from formatted query tail
212+ pull_num = int (query .split ()[1 ])
213+ calls ["nums" ].append (pull_num )
214+ return headers , {
225215 "data" : {
226216 "repository" : {
227217 "pullRequest" : {
228- "closingIssuesReferences" : {"nodes" : [{"number" : self . n }]}
218+ "closingIssuesReferences" : {"nodes" : [{"number" : pull_num }]}
229219 }
230220 }
231221 }
232222 }
233223
234- def fake_post (url , json = None , ** k ):
235- # Extract pull number back from formatted query tail
236- pull_num = int (json ["query" ].split ()[1 ])
237- calls ["nums" ].append (pull_num )
238- return Resp (pull_num )
239-
240- monkeypatch .setattr (pru .requests , "post" , fake_post )
241-
242- r1 = pru .get_issues_for_pr (1 )
243- r2 = pru .get_issues_for_pr (2 )
224+ requester = MockRequester ()
225+ r1 = pru .get_issues_for_pr (1 , requester )
226+ r2 = pru .get_issues_for_pr (2 , requester )
244227 assert r1 == {'OWN/REPO#1' }
245228 assert r2 == {'OWN/REPO#2' }
246229 assert calls ["nums" ] == [1 , 2 ]
0 commit comments