@@ -2,12 +2,14 @@ package edit
22
33import (
44 "bytes"
5+ "errors"
56 "fmt"
67 "io"
78 "net/http"
89 "os"
910 "testing"
1011
12+ "github.com/cli/cli/v2/api"
1113 "github.com/cli/cli/v2/internal/ghrepo"
1214 "github.com/cli/cli/v2/pkg/cmd/release/shared"
1315 "github.com/cli/cli/v2/pkg/cmdutil"
@@ -480,6 +482,99 @@ func mockSuccessfulEditResponse(reg *httpmock.Registry, cb func(params map[strin
480482 reg .Register (matcher , responder )
481483}
482484
485+ func Test_editRelease_httpError (t * testing.T ) {
486+ reg := & httpmock.Registry {}
487+ defer reg .Verify (t )
488+ reg .Register (
489+ func (req * http.Request ) bool {
490+ return req .Method == http .MethodPatch &&
491+ req .URL .EscapedPath () == "/repos/OWNER/REPO/releases/12345" &&
492+ req .URL .Host == "api.github.com"
493+ },
494+ httpmock .StatusStringResponse (404 , `{"message":"Not Found"}` ),
495+ )
496+
497+ httpClient := & http.Client {Transport : reg }
498+ release , err := editRelease (httpClient , ghrepo .New ("OWNER" , "REPO" ), 12345 , map [string ]interface {}{"tag_name" : "v1.2.3" })
499+
500+ var httpErr api.HTTPError
501+ require .ErrorAs (t , err , & httpErr )
502+ assert .Equal (t , http .StatusNotFound , httpErr .StatusCode )
503+ assert .Contains (t , err .Error (), "HTTP 404" )
504+ assert .Nil (t , release )
505+ }
506+
507+ func Test_editRelease_decodeError (t * testing.T ) {
508+ reg := & httpmock.Registry {}
509+ defer reg .Verify (t )
510+ reg .Register (
511+ func (req * http.Request ) bool {
512+ return req .Method == http .MethodPatch &&
513+ req .URL .EscapedPath () == "/repos/OWNER/REPO/releases/12345" &&
514+ req .URL .Host == "api.github.com"
515+ },
516+ httpmock .StatusStringResponse (200 , `{` ),
517+ )
518+
519+ httpClient := & http.Client {Transport : reg }
520+ release , err := editRelease (httpClient , ghrepo .New ("OWNER" , "REPO" ), 12345 , map [string ]interface {}{"tag_name" : "v1.2.3" })
521+
522+ require .Error (t , err )
523+ assert .NotNil (t , release ) // decode was attempted - non-nil pointer even on decode error
524+ }
525+
526+ func Test_editRelease_204 (t * testing.T ) {
527+ reg := & httpmock.Registry {}
528+ defer reg .Verify (t )
529+ reg .Register (
530+ func (req * http.Request ) bool {
531+ return req .Method == http .MethodPatch &&
532+ req .URL .EscapedPath () == "/repos/OWNER/REPO/releases/12345" &&
533+ req .URL .Host == "api.github.com"
534+ },
535+ httpmock .StatusStringResponse (204 , "" ),
536+ )
537+
538+ httpClient := & http.Client {Transport : reg }
539+ release , err := editRelease (httpClient , ghrepo .New ("OWNER" , "REPO" ), 12345 , map [string ]interface {}{"tag_name" : "v1.2.3" })
540+
541+ require .Error (t , err )
542+ assert .Contains (t , err .Error (), "unexpected end of JSON input" )
543+ assert .NotNil (t , release )
544+ }
545+
546+ func Test_editRelease_bodyReadError (t * testing.T ) {
547+ readErr := errors .New ("read: connection reset by peer" )
548+ reg := & httpmock.Registry {}
549+ defer reg .Verify (t )
550+ reg .Register (
551+ func (req * http.Request ) bool {
552+ return req .Method == http .MethodPatch &&
553+ req .URL .EscapedPath () == "/repos/OWNER/REPO/releases/12345" &&
554+ req .URL .Host == "api.github.com"
555+ },
556+ func (_ * http.Request ) (* http.Response , error ) {
557+ return & http.Response {
558+ StatusCode : 200 ,
559+ Body : io .NopCloser (errorReader {err : readErr }),
560+ Header : http.Header {},
561+ }, nil
562+ },
563+ )
564+
565+ httpClient := & http.Client {Transport : reg }
566+ release , err := editRelease (httpClient , ghrepo .New ("OWNER" , "REPO" ), 12345 , map [string ]interface {}{"tag_name" : "v1.2.3" })
567+
568+ require .Error (t , err )
569+ assert .ErrorIs (t , err , readErr )
570+ assert .Nil (t , release )
571+ }
572+
573+ // errorReader always returns the given error on Read, used to simulate body read failures.
574+ type errorReader struct { err error }
575+
576+ func (e errorReader ) Read (_ []byte ) (int , error ) { return 0 , e .err }
577+
483578func boolPtr (b bool ) * bool {
484579 return & b
485580}
0 commit comments