@@ -2,6 +2,7 @@ package main
2
2
3
3
import (
4
4
"context"
5
+ "encoding/json"
5
6
"fmt"
6
7
"net/http"
7
8
"strconv"
@@ -84,32 +85,16 @@ func TestGetPullRequestChangedLines(t *testing.T) {
84
85
"GET" ,
85
86
baseURL ,
86
87
func (req * http.Request ) (* http.Response , error ) {
87
- page := 1
88
- if v , ok := req .URL .Query ()["page" ]; ok && len (v ) > 0 {
89
- if v , err := strconv .Atoi (v [0 ]); err == nil {
90
- page = v
91
- }
92
- }
88
+ page := getPage (req )
93
89
if page - 1 >= len (tt .commitFiles ) {
94
90
return nil , fmt .Errorf ("invalid query value" )
95
91
}
96
-
97
- var links []string
98
- links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="first"` , baseURL , 1 ))
99
- if page - 1 >= 1 {
100
- links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="prev"` , baseURL , page - 1 ))
101
- }
102
- if page + 1 <= len (tt .commitFiles ) {
103
- links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="next"` , baseURL , page + 1 ))
104
- }
105
- links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="last"` , baseURL , len (tt .commitFiles )))
106
-
107
92
resp , err := httpmock .NewJsonResponse (200 , tt .commitFiles [page - 1 ])
108
93
if err != nil {
109
94
return nil , err
110
95
}
111
96
resp .Header .Set ("Content-Type" , "application/json" )
112
- resp .Header .Set ("Link" , strings . Join ( links , ", " ))
97
+ resp .Header .Set ("Link" , generateLinkHeaderValue ( baseURL , page , len ( tt . commitFiles ) ))
113
98
return resp , nil
114
99
},
115
100
)
@@ -149,3 +134,322 @@ func TestGetPullRequestChangedLinesReturnsError(t *testing.T) {
149
134
assert .ErrorContains (t , err , "get all commit files: list commit files: " )
150
135
assert .Zero (t , got )
151
136
}
137
+
138
+ func TestSetLabelOnPullRequest (t * testing.T ) {
139
+ tcs := []struct {
140
+ name string
141
+ labels [][]* github.Label
142
+ size size
143
+
144
+ wantDeletedLabels []string
145
+ wantCreatedLabels []string
146
+ }{
147
+ {
148
+ name : "The pull request doesn't have labels." ,
149
+ labels : [][]* github.Label {
150
+ {},
151
+ },
152
+ size : sizeXL ,
153
+ wantCreatedLabels : []string {
154
+ sizeXL .getLabel (),
155
+ },
156
+ },
157
+ {
158
+ name : "The pull request already has another size label." ,
159
+ labels : [][]* github.Label {
160
+ {
161
+ {
162
+ Name : github .String (sizeL .getLabel ()),
163
+ },
164
+ },
165
+ },
166
+ size : sizeXL ,
167
+ wantDeletedLabels : []string {
168
+ sizeL .getLabel (),
169
+ },
170
+ wantCreatedLabels : []string {
171
+ sizeXL .getLabel (),
172
+ },
173
+ },
174
+ {
175
+ name : "The pull request already has the target size label." ,
176
+ labels : [][]* github.Label {
177
+ {
178
+ {
179
+ Name : github .String (sizeXL .getLabel ()),
180
+ },
181
+ },
182
+ },
183
+ size : sizeXL ,
184
+ },
185
+ {
186
+ name : "The pull request has another size label and non-size labels." ,
187
+ labels : [][]* github.Label {
188
+ {
189
+ {
190
+ Name : github .String ("foo" ),
191
+ },
192
+ },
193
+ {
194
+ {
195
+ Name : github .String ("bar" ),
196
+ },
197
+ {
198
+ Name : github .String (sizeS .getLabel ()),
199
+ },
200
+ {
201
+ Name : github .String ("baz" ),
202
+ },
203
+ },
204
+ {
205
+ {
206
+ Name : github .String ("qux" ),
207
+ },
208
+ },
209
+ },
210
+ size : sizeM ,
211
+ wantDeletedLabels : []string {
212
+ sizeS .getLabel (),
213
+ },
214
+ wantCreatedLabels : []string {
215
+ sizeM .getLabel (),
216
+ },
217
+ },
218
+ {
219
+ name : "The pull request has multiple size labels." ,
220
+ labels : [][]* github.Label {
221
+ {
222
+ {
223
+ Name : github .String (sizeL .getLabel ()),
224
+ },
225
+ {
226
+ Name : github .String (sizeM .getLabel ()),
227
+ },
228
+ },
229
+ },
230
+ size : sizeXL ,
231
+ wantDeletedLabels : []string {
232
+ sizeL .getLabel (),
233
+ sizeM .getLabel (),
234
+ },
235
+ wantCreatedLabels : []string {
236
+ sizeXL .getLabel (),
237
+ },
238
+ },
239
+ }
240
+ for _ , tt := range tcs {
241
+ t .Run (tt .name , func (t * testing.T ) {
242
+ client := & http.Client {}
243
+ httpmock .ActivateNonDefault (client )
244
+ defer httpmock .DeactivateAndReset ()
245
+
246
+ var (
247
+ gotDeletedLabels []string
248
+ gotCreatedLabels []string
249
+ )
250
+ const baseURL = "https://api.github.com/repos/kkohtaka/gh-actions-pr-size/issues/42/labels"
251
+ httpmock .RegisterResponder (
252
+ "GET" ,
253
+ baseURL ,
254
+ func (req * http.Request ) (* http.Response , error ) {
255
+ page := getPage (req )
256
+ if page - 1 >= len (tt .labels ) {
257
+ return nil , fmt .Errorf ("invalid query value" )
258
+ }
259
+ resp , err := httpmock .NewJsonResponse (200 , tt .labels [page - 1 ])
260
+ if err != nil {
261
+ return nil , err
262
+ }
263
+ resp .Header .Set ("Content-Type" , "application/json" )
264
+ resp .Header .Set ("Link" , generateLinkHeaderValue (baseURL , page , len (tt .labels )))
265
+ return resp , nil
266
+ },
267
+ )
268
+ httpmock .RegisterResponder (
269
+ "DELETE" ,
270
+ fmt .Sprintf ("=~^%s/(.*)$" , baseURL ),
271
+ func (req * http.Request ) (* http.Response , error ) {
272
+ label , err := httpmock .GetSubmatch (req , 1 )
273
+ if err != nil {
274
+ return httpmock .NewStringResponse (400 , "unable to get a label name" ), nil
275
+ }
276
+ gotDeletedLabels = append (gotDeletedLabels , label )
277
+ resp := httpmock .NewBytesResponse (200 , nil )
278
+ resp .Header .Set ("Content-Type" , "application/json" )
279
+ return resp , nil
280
+ },
281
+ )
282
+ httpmock .RegisterResponder (
283
+ "POST" ,
284
+ baseURL ,
285
+ func (req * http.Request ) (* http.Response , error ) {
286
+ var labels []string
287
+ if err := json .NewDecoder (req .Body ).Decode (& labels ); err != nil {
288
+ return httpmock .NewStringResponse (
289
+ 400 ,
290
+ fmt .Sprintf ("unable to decode request body: %v" , err ),
291
+ ), nil
292
+ }
293
+ gotCreatedLabels = append (gotCreatedLabels , labels ... )
294
+ resp := httpmock .NewBytesResponse (200 , nil )
295
+ resp .Header .Set ("Content-Type" , "application/json" )
296
+ return resp , nil
297
+ },
298
+ )
299
+
300
+ err := setLabelOnPullRequest (
301
+ context .Background (),
302
+ github .NewClient (client ),
303
+ "kkohtaka" ,
304
+ "gh-actions-pr-size" ,
305
+ 42 ,
306
+ tt .size ,
307
+ )
308
+ require .NoError (t , err )
309
+
310
+ assert .Equal (t , tt .wantDeletedLabels , gotDeletedLabels )
311
+ assert .Equal (t , tt .wantCreatedLabels , gotCreatedLabels )
312
+ })
313
+ }
314
+ }
315
+
316
+ func TestSetLabelOnPullRequestReturnsError (t * testing.T ) {
317
+ const baseURL = "https://api.github.com/repos/kkohtaka/gh-actions-pr-size/issues/42/labels"
318
+
319
+ t .Run (
320
+ "GitHub API that listing issue labels returns an error." ,
321
+ func (t * testing.T ) {
322
+ client := & http.Client {}
323
+ httpmock .ActivateNonDefault (client )
324
+ defer httpmock .DeactivateAndReset ()
325
+
326
+ httpmock .RegisterResponder (
327
+ "GET" ,
328
+ baseURL ,
329
+ httpmock .NewErrorResponder (fmt .Errorf ("test for error handling" )),
330
+ )
331
+
332
+ err := setLabelOnPullRequest (
333
+ context .Background (),
334
+ github .NewClient (client ),
335
+ "kkohtaka" ,
336
+ "gh-actions-pr-size" ,
337
+ 42 ,
338
+ sizeXL ,
339
+ )
340
+ assert .ErrorContains (t , err , "list labels by issue: " )
341
+ },
342
+ )
343
+
344
+ t .Run (
345
+ "GitHub API that deleting an issue label returns an error." ,
346
+ func (t * testing.T ) {
347
+ client := & http.Client {}
348
+ httpmock .ActivateNonDefault (client )
349
+ defer httpmock .DeactivateAndReset ()
350
+
351
+ httpmock .RegisterResponder (
352
+ "GET" ,
353
+ baseURL ,
354
+ func (req * http.Request ) (* http.Response , error ) {
355
+ resp , err := httpmock .NewJsonResponse (200 , []* github.Label {
356
+ {
357
+ Name : github .String (sizeL .getLabel ()),
358
+ },
359
+ })
360
+ if err != nil {
361
+ return nil , err
362
+ }
363
+ resp .Header .Set ("Content-Type" , "application/json" )
364
+ resp .Header .Set ("Link" , generateLinkHeaderValue (baseURL , 1 , 1 ))
365
+ return resp , nil
366
+ },
367
+ )
368
+ httpmock .RegisterResponder (
369
+ "DELETE" ,
370
+ fmt .Sprintf ("%s/%s" , baseURL , sizeL .getLabel ()),
371
+ httpmock .NewErrorResponder (fmt .Errorf ("test for error handling" )),
372
+ )
373
+
374
+ err := setLabelOnPullRequest (
375
+ context .Background (),
376
+ github .NewClient (client ),
377
+ "kkohtaka" ,
378
+ "gh-actions-pr-size" ,
379
+ 42 ,
380
+ sizeXL ,
381
+ )
382
+ assert .ErrorContains (t , err , "remove a label from a pull request: " )
383
+ },
384
+ )
385
+
386
+ t .Run (
387
+ "GitHub API that creating an issue label returns an error." ,
388
+ func (t * testing.T ) {
389
+ client := & http.Client {}
390
+ httpmock .ActivateNonDefault (client )
391
+ defer httpmock .DeactivateAndReset ()
392
+
393
+ httpmock .RegisterResponder (
394
+ "GET" ,
395
+ baseURL ,
396
+ func (req * http.Request ) (* http.Response , error ) {
397
+ resp , err := httpmock .NewJsonResponse (200 , []* github.Label {
398
+ {
399
+ Name : github .String (sizeL .getLabel ()),
400
+ },
401
+ })
402
+ if err != nil {
403
+ return nil , err
404
+ }
405
+ resp .Header .Set ("Content-Type" , "application/json" )
406
+ resp .Header .Set ("Link" , generateLinkHeaderValue (baseURL , 1 , 1 ))
407
+ return resp , nil
408
+ },
409
+ )
410
+ httpmock .RegisterResponder (
411
+ "DELETE" ,
412
+ fmt .Sprintf ("%s/%s" , baseURL , sizeL .getLabel ()),
413
+ httpmock .NewBytesResponder (200 , nil ),
414
+ )
415
+ httpmock .RegisterResponder (
416
+ "POST" ,
417
+ baseURL ,
418
+ httpmock .NewErrorResponder (fmt .Errorf ("test for error handling" )),
419
+ )
420
+
421
+ err := setLabelOnPullRequest (
422
+ context .Background (),
423
+ github .NewClient (client ),
424
+ "kkohtaka" ,
425
+ "gh-actions-pr-size" ,
426
+ 42 ,
427
+ sizeXL ,
428
+ )
429
+ assert .ErrorContains (t , err , "add a label to a pull request: " )
430
+ },
431
+ )
432
+ }
433
+
434
+ func getPage (req * http.Request ) int {
435
+ page := 1
436
+ if v , ok := req .URL .Query ()["page" ]; ok && len (v ) > 0 {
437
+ if v , err := strconv .Atoi (v [0 ]); err == nil {
438
+ page = v
439
+ }
440
+ }
441
+ return page
442
+ }
443
+
444
+ func generateLinkHeaderValue (baseURL string , page , amount int ) string {
445
+ var links []string
446
+ links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="first"` , baseURL , 1 ))
447
+ if page - 1 >= 1 {
448
+ links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="prev"` , baseURL , page - 1 ))
449
+ }
450
+ if page + 1 <= amount {
451
+ links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="next"` , baseURL , page + 1 ))
452
+ }
453
+ links = append (links , fmt .Sprintf (`<%s?page=%d>; rel="last"` , baseURL , amount ))
454
+ return strings .Join (links , ", " )
455
+ }
0 commit comments