github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudwrapper/errors_test.go (about) 1 package cloudwrapper 2 3 import ( 4 "context" 5 "io/ioutil" 6 "net/http" 7 "strings" 8 "testing" 9 10 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/session" 11 "github.com/stretchr/testify/require" 12 "github.com/tj/assert" 13 ) 14 15 func TestNewError(t *testing.T) { 16 sess, err := session.New() 17 require.NoError(t, err) 18 19 req, err := http.NewRequest( 20 http.MethodHead, 21 "/", 22 nil) 23 require.NoError(t, err) 24 25 tests := map[string]struct { 26 response *http.Response 27 expected *Error 28 }{ 29 "Bad request 400": { 30 response: &http.Response{ 31 Status: "Internal Server Error", 32 StatusCode: http.StatusBadRequest, 33 Body: ioutil.NopCloser(strings.NewReader( 34 `{ 35 "type": "bad-request", 36 "title": "Bad Request", 37 "instance": "30109837-7ea6-4b14-a41d-50cfb12a4b03", 38 "status": 400, 39 "detail": "Erroneous data input", 40 "errors": [ 41 { 42 "type": "bad-request", 43 "title": "Bad Request", 44 "detail": "Configuration with name UpdateConfiguration already exists in account 1234-3KNWKV.", 45 "illegalValue": "UpdateConfiguration", 46 "illegalParameter": "configurationName" 47 }, 48 { 49 "type": "bad-request", 50 "title": "Bad Request", 51 "detail": "One or more ARL Property is already used in another configuration.", 52 "illegalValue": [ 53 { 54 "propertyId": "123010" 55 } 56 ], 57 "illegalParameter": "properties" 58 } 59 ] 60 }`), 61 ), 62 Request: req, 63 }, 64 expected: &Error{ 65 Type: "bad-request", 66 Title: "Bad Request", 67 Instance: "30109837-7ea6-4b14-a41d-50cfb12a4b03", 68 Status: http.StatusBadRequest, 69 Detail: "Erroneous data input", 70 Errors: []ErrorItem{ 71 { 72 Type: "bad-request", 73 Title: "Bad Request", 74 Detail: "Configuration with name UpdateConfiguration already exists in account 1234-3KNWKV.", 75 IllegalValue: "UpdateConfiguration", 76 IllegalParameter: "configurationName", 77 }, 78 { 79 Type: "bad-request", 80 Title: "Bad Request", 81 Detail: "One or more ARL Property is already used in another configuration.", 82 IllegalValue: []any{map[string]any{"propertyId": "123010"}}, 83 IllegalParameter: "properties", 84 }, 85 }, 86 }, 87 }, 88 "invalid response body, assign status code": { 89 response: &http.Response{ 90 Status: "Internal Server Error", 91 StatusCode: http.StatusInternalServerError, 92 Body: ioutil.NopCloser(strings.NewReader( 93 `test`), 94 ), 95 Request: req, 96 }, 97 expected: &Error{ 98 Title: "Failed to unmarshal error body. Cloud Wrapper API failed. Check details for more information.", 99 Detail: "test", 100 Status: http.StatusInternalServerError, 101 }, 102 }, 103 } 104 for name, test := range tests { 105 t.Run(name, func(t *testing.T) { 106 res := Client(sess).(*cloudwrapper).Error(test.response) 107 assert.Equal(t, test.expected, res) 108 }) 109 } 110 } 111 112 func TestIs(t *testing.T) { 113 tests := map[string]struct { 114 err Error 115 target Error 116 expected bool 117 }{ 118 "different error code": { 119 err: Error{Status: 404}, 120 target: Error{Status: 401}, 121 expected: false, 122 }, 123 "same error code": { 124 err: Error{Status: 404}, 125 target: Error{Status: 404}, 126 expected: true, 127 }, 128 "same error code and title": { 129 err: Error{Status: 404, Title: "some error"}, 130 target: Error{Status: 404, Title: "some error"}, 131 expected: true, 132 }, 133 "same error code and different error message": { 134 err: Error{Status: 404, Title: "some error"}, 135 target: Error{Status: 404, Title: "other error"}, 136 expected: false, 137 }, 138 } 139 140 for name, test := range tests { 141 t.Run(name, func(t *testing.T) { 142 assert.Equal(t, test.err.Is(&test.target), test.expected) 143 }) 144 } 145 } 146 147 func TestJsonErrorUnmarshalling(t *testing.T) { 148 req, err := http.NewRequestWithContext( 149 context.TODO(), 150 http.MethodHead, 151 "/", 152 nil) 153 require.NoError(t, err) 154 tests := map[string]struct { 155 input *http.Response 156 expected *Error 157 }{ 158 "API failure with HTML response": { 159 input: &http.Response{ 160 Request: req, 161 Status: "OK", 162 Body: ioutil.NopCloser(strings.NewReader(`<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>`))}, 163 expected: &Error{ 164 Type: "", 165 Title: "Failed to unmarshal error body. Cloud Wrapper API failed. Check details for more information.", 166 Detail: "<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>", 167 }, 168 }, 169 "API failure with plain text response": { 170 input: &http.Response{ 171 Request: req, 172 Status: "OK", 173 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"))}, 174 expected: &Error{ 175 Type: "", 176 Title: "Failed to unmarshal error body. Cloud Wrapper API failed. Check details for more information.", 177 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", 178 }, 179 }, 180 "API failure with XML response": { 181 input: &http.Response{ 182 Request: req, 183 Status: "OK", 184 Body: ioutil.NopCloser(strings.NewReader(`<Root><Item id="1" name="Example" /></Root>`))}, 185 expected: &Error{ 186 Type: "", 187 Title: "Failed to unmarshal error body. Cloud Wrapper API failed. Check details for more information.", 188 Detail: "<Root><Item id=\"1\" name=\"Example\" /></Root>", 189 }, 190 }, 191 } 192 193 for name, test := range tests { 194 t.Run(name, func(t *testing.T) { 195 sess, _ := session.New() 196 c := cloudwrapper{ 197 Session: sess, 198 } 199 assert.Equal(t, test.expected, c.Error(test.input)) 200 }) 201 } 202 }