github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/errors_test.go (about) 1 package cloudlets 2 3 import ( 4 "context" 5 "encoding/json" 6 "io/ioutil" 7 "net/http" 8 "strings" 9 "testing" 10 11 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/session" 12 "github.com/stretchr/testify/require" 13 "github.com/tj/assert" 14 ) 15 16 func TestNewError(t *testing.T) { 17 sess, err := session.New() 18 require.NoError(t, err) 19 20 req, err := http.NewRequest( 21 http.MethodHead, 22 "/", 23 nil) 24 require.NoError(t, err) 25 26 tests := map[string]struct { 27 response *http.Response 28 expected *Error 29 }{ 30 "valid response, status code 500": { 31 response: &http.Response{ 32 Status: "Internal Server Error", 33 StatusCode: http.StatusInternalServerError, 34 Body: ioutil.NopCloser(strings.NewReader( 35 `{"type":"a","title":"b","detail":"c"}`), 36 ), 37 Request: req, 38 }, 39 expected: &Error{ 40 Type: "a", 41 Title: "b", 42 Detail: "c", 43 StatusCode: http.StatusInternalServerError, 44 }, 45 }, 46 "invalid response body, assign status code": { 47 response: &http.Response{ 48 Status: "Internal Server Error", 49 StatusCode: http.StatusInternalServerError, 50 Body: ioutil.NopCloser(strings.NewReader( 51 `test`), 52 ), 53 Request: req, 54 }, 55 expected: &Error{ 56 Title: "Failed to unmarshal error body. Cloudlets API failed. Check details for more information.", 57 Detail: "test", 58 StatusCode: http.StatusInternalServerError, 59 }, 60 }, 61 } 62 for name, test := range tests { 63 t.Run(name, func(t *testing.T) { 64 res := Client(sess).(*cloudlets).Error(test.response) 65 assert.Equal(t, test.expected, res) 66 }) 67 } 68 } 69 70 func TestAs(t *testing.T) { 71 someErrorMarshalled, _ := json.Marshal("some error") 72 tests := map[string]struct { 73 err Error 74 target Error 75 expected bool 76 }{ 77 "different error code": { 78 err: Error{StatusCode: 404}, 79 target: Error{StatusCode: 401}, 80 expected: false, 81 }, 82 "same error code": { 83 err: Error{StatusCode: 404}, 84 target: Error{StatusCode: 404}, 85 expected: true, 86 }, 87 "same error code and error message": { 88 err: Error{StatusCode: 404, Errors: someErrorMarshalled}, 89 target: Error{StatusCode: 404, Errors: someErrorMarshalled}, 90 expected: true, 91 }, 92 "same error code and different error message": { 93 err: Error{StatusCode: 404, Errors: someErrorMarshalled}, 94 target: Error{StatusCode: 404}, 95 expected: false, 96 }, 97 } 98 99 for name, test := range tests { 100 t.Run(name, func(t *testing.T) { 101 assert.Equal(t, test.err.Is(&test.target), test.expected) 102 }) 103 } 104 } 105 106 func TestJsonErrorUnmarshalling(t *testing.T) { 107 req, err := http.NewRequestWithContext( 108 context.TODO(), 109 http.MethodHead, 110 "/", 111 nil) 112 require.NoError(t, err) 113 tests := map[string]struct { 114 input *http.Response 115 expected *Error 116 }{ 117 "API failure with HTML response": { 118 input: &http.Response{ 119 Request: req, 120 Status: "OK", 121 StatusCode: http.StatusServiceUnavailable, 122 Body: ioutil.NopCloser(strings.NewReader(`<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>`))}, 123 expected: &Error{ 124 Type: "", 125 Title: "Failed to unmarshal error body. Cloudlets API failed. Check details for more information.", 126 Detail: "<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>", 127 StatusCode: http.StatusServiceUnavailable, 128 }, 129 }, 130 "API failure with plain text response": { 131 input: &http.Response{ 132 Request: req, 133 Status: "OK", 134 StatusCode: http.StatusServiceUnavailable, 135 Body: ioutil.NopCloser(strings.NewReader("Your request did not succeed as this operation has reached the limit for your account. Please try after 2024-01-16T15:20:55.945Z"))}, 136 expected: &Error{ 137 Type: "", 138 Title: "Failed to unmarshal error body. Cloudlets API failed. Check details for more information.", 139 Detail: "Your request did not succeed as this operation has reached the limit for your account. Please try after 2024-01-16T15:20:55.945Z", 140 StatusCode: http.StatusServiceUnavailable, 141 }, 142 }, 143 "API failure with XML response": { 144 input: &http.Response{ 145 Request: req, 146 Status: "OK", 147 StatusCode: http.StatusServiceUnavailable, 148 Body: ioutil.NopCloser(strings.NewReader(`<Root><Item id="1" name="Example" /></Root>`))}, 149 expected: &Error{ 150 Type: "", 151 Title: "Failed to unmarshal error body. Cloudlets API failed. Check details for more information.", 152 Detail: "<Root><Item id=\"1\" name=\"Example\" /></Root>", 153 StatusCode: http.StatusServiceUnavailable, 154 }, 155 }, 156 } 157 158 for name, test := range tests { 159 t.Run(name, func(t *testing.T) { 160 sess, _ := session.New() 161 c := cloudlets{ 162 Session: sess, 163 } 164 assert.Equal(t, test.expected, c.Error(test.input)) 165 }) 166 } 167 }