@@ -69,6 +69,14 @@ describe("enqueue-pullrequest action", () => {
6969 } ;
7070 }
7171
72+ // Mocks for each GraphQL call in order.
73+ const mqEnabled = { repository : { mergeQueue : { id : "MQ_1" } } } ;
74+ const mqDisabled = { repository : { mergeQueue : null } } ;
75+
76+ function mockEnqueue ( id = "MQE_1" , position = 1 ) {
77+ return { enqueuePullRequest : { mergeQueueEntry : { id, state : "QUEUED" , position } } } ;
78+ }
79+
7280 // Loads the action module, which immediately calls run().
7381 async function runAction ( ) {
7482 require ( "../index" ) ;
@@ -81,25 +89,41 @@ describe("enqueue-pullrequest action", () => {
8189 test ( "enqueues an eligible PR" , async ( ) => {
8290 setupInputs ( ) ;
8391 mockOctokit . graphql
84- . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
85- . mockResolvedValueOnce ( {
86- enqueuePullRequest : {
87- mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } ,
88- } ,
89- } ) ;
92+ . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } ) // getPRDetails
93+ . mockResolvedValueOnce ( mqEnabled ) // isMergeQueueEnabled
94+ . mockResolvedValueOnce ( mockEnqueue ( ) ) ; // enqueuePullRequest
9095
9196 await runAction ( ) ;
9297
93- expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 2 ) ;
94- // Second call must be the enqueuePullRequest mutation with the PR node ID
98+ expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 3 ) ;
9599 expect ( mockOctokit . graphql ) . toHaveBeenNthCalledWith (
96100 2 ,
101+ expect . stringContaining ( "MergeQueueEnabled" ) ,
102+ expect . objectContaining ( { branch : "main" } )
103+ ) ;
104+ expect ( mockOctokit . graphql ) . toHaveBeenNthCalledWith (
105+ 3 ,
97106 expect . stringContaining ( "enqueuePullRequest" ) ,
98107 { prId : "PR_abc123" }
99108 ) ;
100109 expect ( core . setFailed ) . not . toHaveBeenCalled ( ) ;
101110 } ) ;
102111
112+ test ( "warns and skips when merge queue is not enabled for the base branch" , async ( ) => {
113+ setupInputs ( ) ;
114+ mockOctokit . graphql
115+ . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
116+ . mockResolvedValueOnce ( mqDisabled ) ;
117+
118+ await runAction ( ) ;
119+
120+ expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 2 ) ;
121+ expect ( core . warning ) . toHaveBeenCalledWith (
122+ expect . stringContaining ( "merge queue is not enabled" )
123+ ) ;
124+ expect ( core . setFailed ) . not . toHaveBeenCalled ( ) ;
125+ } ) ;
126+
103127 test ( "skips a closed PR without calling enqueue" , async ( ) => {
104128 setupInputs ( ) ;
105129 mockOctokit . graphql . mockResolvedValueOnce ( {
@@ -127,20 +151,15 @@ describe("enqueue-pullrequest action", () => {
127151 test ( "enqueues a draft PR when skip-drafts=false" , async ( ) => {
128152 setupInputs ( { "skip-drafts" : "false" } ) ;
129153 mockOctokit . graphql
130- . mockResolvedValueOnce ( {
131- repository : { pullRequest : makePRPayload ( { isDraft : true } ) } ,
132- } )
133- . mockResolvedValueOnce ( {
134- enqueuePullRequest : {
135- mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } ,
136- } ,
137- } ) ;
154+ . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( { isDraft : true } ) } } )
155+ . mockResolvedValueOnce ( mqEnabled )
156+ . mockResolvedValueOnce ( mockEnqueue ( ) ) ;
138157
139158 await runAction ( ) ;
140159
141- expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 2 ) ;
160+ expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 3 ) ;
142161 expect ( mockOctokit . graphql ) . toHaveBeenNthCalledWith (
143- 2 ,
162+ 3 ,
144163 expect . stringContaining ( "enqueuePullRequest" ) ,
145164 expect . anything ( )
146165 ) ;
@@ -161,20 +180,15 @@ describe("enqueue-pullrequest action", () => {
161180 test ( "enqueues PR with no label requirement when label input is empty" , async ( ) => {
162181 setupInputs ( { label : "" } ) ;
163182 mockOctokit . graphql
164- . mockResolvedValueOnce ( {
165- repository : { pullRequest : makePRPayload ( { labels : { nodes : [ ] } } ) } ,
166- } )
167- . mockResolvedValueOnce ( {
168- enqueuePullRequest : {
169- mergeQueueEntry : { id : "MQE_2" , state : "QUEUED" , position : 1 } ,
170- } ,
171- } ) ;
183+ . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( { labels : { nodes : [ ] } } ) } } )
184+ . mockResolvedValueOnce ( mqEnabled )
185+ . mockResolvedValueOnce ( mockEnqueue ( "MQE_2" ) ) ;
172186
173187 await runAction ( ) ;
174188
175- expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 2 ) ;
189+ expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 3 ) ;
176190 expect ( mockOctokit . graphql ) . toHaveBeenNthCalledWith (
177- 2 ,
191+ 3 ,
178192 expect . stringContaining ( "enqueuePullRequest" ) ,
179193 expect . anything ( )
180194 ) ;
@@ -185,9 +199,7 @@ describe("enqueue-pullrequest action", () => {
185199 mockOctokit . graphql . mockResolvedValueOnce ( {
186200 repository : {
187201 pullRequest : makePRPayload ( {
188- labels : {
189- nodes : [ { name : "enqueue-pullrequest" } , { name : "wip" } ] ,
190- } ,
202+ labels : { nodes : [ { name : "enqueue-pullrequest" } , { name : "wip" } ] } ,
191203 } ) ,
192204 } ,
193205 } ) ;
@@ -216,9 +228,7 @@ describe("enqueue-pullrequest action", () => {
216228 test ( "skips PR with insufficient required approvals" , async ( ) => {
217229 setupInputs ( { "required-approvals" : "2" } ) ;
218230 mockOctokit . graphql . mockResolvedValueOnce ( {
219- repository : {
220- pullRequest : makePRPayload ( { reviews : { totalCount : 1 } } ) ,
221- } ,
231+ repository : { pullRequest : makePRPayload ( { reviews : { totalCount : 1 } } ) } ,
222232 } ) ;
223233
224234 await runAction ( ) ;
@@ -230,28 +240,19 @@ describe("enqueue-pullrequest action", () => {
230240 test ( "enqueues PR that meets the required approvals threshold" , async ( ) => {
231241 setupInputs ( { "required-approvals" : "2" } ) ;
232242 mockOctokit . graphql
233- . mockResolvedValueOnce ( {
234- repository : {
235- pullRequest : makePRPayload ( { reviews : { totalCount : 2 } } ) ,
236- } ,
237- } )
238- . mockResolvedValueOnce ( {
239- enqueuePullRequest : {
240- mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } ,
241- } ,
242- } ) ;
243+ . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( { reviews : { totalCount : 2 } } ) } } )
244+ . mockResolvedValueOnce ( mqEnabled )
245+ . mockResolvedValueOnce ( mockEnqueue ( ) ) ;
243246
244247 await runAction ( ) ;
245248
246- expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 2 ) ;
249+ expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 3 ) ;
247250 } ) ;
248251
249252 test ( "skips PR targeting a branch not in base-branches list" , async ( ) => {
250253 setupInputs ( { "base-branches" : "main,master" } ) ;
251254 mockOctokit . graphql . mockResolvedValueOnce ( {
252- repository : {
253- pullRequest : makePRPayload ( { baseRefName : "develop" } ) ,
254- } ,
255+ repository : { pullRequest : makePRPayload ( { baseRefName : "develop" } ) } ,
255256 } ) ;
256257
257258 await runAction ( ) ;
@@ -268,6 +269,7 @@ describe("enqueue-pullrequest action", () => {
268269 setupInputs ( ) ;
269270 mockOctokit . graphql
270271 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
272+ . mockResolvedValueOnce ( mqEnabled )
271273 . mockRejectedValueOnce ( new Error ( "Branch protection not enabled" ) ) ;
272274
273275 await runAction ( ) ;
@@ -286,9 +288,7 @@ describe("enqueue-pullrequest action", () => {
286288
287289 await runAction ( ) ;
288290
289- expect ( core . warning ) . toHaveBeenCalledWith (
290- expect . stringContaining ( "not found" )
291- ) ;
291+ expect ( core . warning ) . toHaveBeenCalledWith ( expect . stringContaining ( "not found" ) ) ;
292292 } ) ;
293293
294294 test ( "logs warning and continues when getPRDetails throws" , async ( ) => {
@@ -316,11 +316,8 @@ describe("enqueue-pullrequest action", () => {
316316 } ;
317317 mockOctokit . graphql
318318 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
319- . mockResolvedValueOnce ( {
320- enqueuePullRequest : {
321- mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } ,
322- } ,
323- } ) ;
319+ . mockResolvedValueOnce ( mqEnabled )
320+ . mockResolvedValueOnce ( mockEnqueue ( ) ) ;
324321
325322 await runAction ( ) ;
326323
@@ -339,11 +336,8 @@ describe("enqueue-pullrequest action", () => {
339336 } ;
340337 mockOctokit . graphql
341338 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
342- . mockResolvedValueOnce ( {
343- enqueuePullRequest : {
344- mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } ,
345- } ,
346- } ) ;
339+ . mockResolvedValueOnce ( mqEnabled )
340+ . mockResolvedValueOnce ( mockEnqueue ( ) ) ;
347341
348342 await runAction ( ) ;
349343
@@ -357,20 +351,16 @@ describe("enqueue-pullrequest action", () => {
357351 setupInputs ( ) ;
358352 github . context = {
359353 eventName : "check_run" ,
360- payload : {
361- check_run : { pull_requests : [ { number : 10 } , { number : 11 } ] } ,
362- } ,
354+ payload : { check_run : { pull_requests : [ { number : 10 } , { number : 11 } ] } } ,
363355 repo : { owner : "acme" , repo : "my-repo" } ,
364356 } ;
365357 mockOctokit . graphql
366358 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
367- . mockResolvedValueOnce ( {
368- enqueuePullRequest : { mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } } ,
369- } )
359+ . mockResolvedValueOnce ( mqEnabled )
360+ . mockResolvedValueOnce ( mockEnqueue ( "MQE_1" ) )
370361 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
371- . mockResolvedValueOnce ( {
372- enqueuePullRequest : { mergeQueueEntry : { id : "MQE_2" , state : "QUEUED" , position : 2 } } ,
373- } ) ;
362+ . mockResolvedValueOnce ( mqEnabled )
363+ . mockResolvedValueOnce ( mockEnqueue ( "MQE_2" , 2 ) ) ;
374364
375365 await runAction ( ) ;
376366
@@ -388,16 +378,13 @@ describe("enqueue-pullrequest action", () => {
388378 setupInputs ( ) ;
389379 github . context = {
390380 eventName : "check_suite" ,
391- payload : {
392- check_suite : { pull_requests : [ { number : 20 } ] } ,
393- } ,
381+ payload : { check_suite : { pull_requests : [ { number : 20 } ] } } ,
394382 repo : { owner : "acme" , repo : "my-repo" } ,
395383 } ;
396384 mockOctokit . graphql
397385 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
398- . mockResolvedValueOnce ( {
399- enqueuePullRequest : { mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } } ,
400- } ) ;
386+ . mockResolvedValueOnce ( mqEnabled )
387+ . mockResolvedValueOnce ( mockEnqueue ( ) ) ;
401388
402389 await runAction ( ) ;
403390
@@ -417,21 +404,19 @@ describe("enqueue-pullrequest action", () => {
417404 mockOctokit . paginate . mockResolvedValue ( [ { number : 5 } , { number : 6 } ] ) ;
418405 mockOctokit . graphql
419406 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
420- . mockResolvedValueOnce ( {
421- enqueuePullRequest : { mergeQueueEntry : { id : "MQE_1" , state : "QUEUED" , position : 1 } } ,
422- } )
407+ . mockResolvedValueOnce ( mqEnabled )
408+ . mockResolvedValueOnce ( mockEnqueue ( "MQE_1" ) )
423409 . mockResolvedValueOnce ( { repository : { pullRequest : makePRPayload ( ) } } )
424- . mockResolvedValueOnce ( {
425- enqueuePullRequest : { mergeQueueEntry : { id : "MQE_2" , state : "QUEUED" , position : 2 } } ,
426- } ) ;
410+ . mockResolvedValueOnce ( mqEnabled )
411+ . mockResolvedValueOnce ( mockEnqueue ( "MQE_2" , 2 ) ) ;
427412
428413 await runAction ( ) ;
429414
430415 expect ( mockOctokit . paginate ) . toHaveBeenCalledWith (
431416 mockOctokit . rest . pulls . list ,
432417 expect . objectContaining ( { state : "open" } )
433418 ) ;
434- expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 4 ) ;
419+ expect ( mockOctokit . graphql ) . toHaveBeenCalledTimes ( 6 ) ;
435420 } ) ;
436421
437422 test ( "workflow_dispatch event with no open PRs logs and exits cleanly" , async ( ) => {
0 commit comments