github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/papi/errors_test.go (about) 1 package papi 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "strings" 9 "testing" 10 11 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/session" 12 "github.com/akamai/AkamaiOPEN-edgegrid-golang/v8/pkg/tools" 13 "github.com/stretchr/testify/require" 14 "github.com/tj/assert" 15 ) 16 17 func TestNewError(t *testing.T) { 18 sess, err := session.New() 19 require.NoError(t, err) 20 21 req, err := http.NewRequestWithContext( 22 context.TODO(), 23 http.MethodHead, 24 "/", 25 nil) 26 require.NoError(t, err) 27 28 tests := map[string]struct { 29 response *http.Response 30 expected *Error 31 }{ 32 "valid response, status code 500": { 33 response: &http.Response{ 34 Status: "Internal Server Error", 35 StatusCode: http.StatusInternalServerError, 36 Body: ioutil.NopCloser(strings.NewReader( 37 `{"type":"a","title":"b","detail":"c"}`), 38 ), 39 Request: req, 40 }, 41 expected: &Error{ 42 Type: "a", 43 Title: "b", 44 Detail: "c", 45 StatusCode: http.StatusInternalServerError, 46 }, 47 }, 48 "invalid response body, assign status code": { 49 response: &http.Response{ 50 Status: "Internal Server Error", 51 StatusCode: http.StatusInternalServerError, 52 Body: ioutil.NopCloser(strings.NewReader( 53 `test`), 54 ), 55 Request: req, 56 }, 57 expected: &Error{ 58 Title: "Failed to unmarshal error body. PAPI API failed. Check details for more information.", 59 Detail: "test", 60 StatusCode: http.StatusInternalServerError, 61 }, 62 }, 63 } 64 for name, test := range tests { 65 t.Run(name, func(t *testing.T) { 66 res := Client(sess).(*papi).Error(test.response) 67 assert.Equal(t, test.expected, res) 68 }) 69 } 70 } 71 72 func TestErrorIs(t *testing.T) { 73 tests := map[string]struct { 74 err Error 75 given error 76 expected bool 77 }{ 78 "is ErrSBDNotEnabled": { 79 err: Error{ 80 StatusCode: http.StatusForbidden, 81 Type: "https://problems.luna.akamaiapis.net/papi/v0/property-version-hostname/default-cert-provisioning-unavailable", 82 }, 83 given: ErrSBDNotEnabled, 84 expected: true, 85 }, 86 "is wrapped ErrSBDNotEnabled": { 87 err: Error{ 88 StatusCode: http.StatusForbidden, 89 Type: "https://problems.luna.akamaiapis.net/papi/v0/property-version-hostname/default-cert-provisioning-unavailable", 90 }, 91 given: fmt.Errorf("oops: %w", ErrSBDNotEnabled), 92 expected: true, 93 }, 94 "is ErrDefaultCertLimitReached": { 95 err: Error{ 96 StatusCode: http.StatusTooManyRequests, 97 LimitKey: "DEFAULT_CERTS_PER_CONTRACT", 98 Remaining: tools.IntPtr(0), 99 }, 100 given: ErrDefaultCertLimitReached, 101 expected: true, 102 }, 103 "is not ErrSBDNotEnabled": { 104 err: Error{ 105 StatusCode: http.StatusTooManyRequests, 106 LimitKey: "DEFAULT_CERTS_PER_CONTRACT", 107 Remaining: tools.IntPtr(0), 108 }, 109 given: ErrSBDNotEnabled, 110 expected: false, 111 }, 112 "is not ErrDefaultCertLimitReached": { 113 err: Error{ 114 StatusCode: http.StatusForbidden, 115 Type: "https://problems.luna.akamaiapis.net/papi/v0/property-version-hostname/default-cert-provisioning-unavailable", 116 }, 117 given: ErrDefaultCertLimitReached, 118 expected: false, 119 }, 120 } 121 122 for name, test := range tests { 123 t.Run(name, func(t *testing.T) { 124 res := test.err.Is(test.given) 125 assert.Equal(t, test.expected, res) 126 }) 127 } 128 } 129 130 func TestJsonErrorUnmarshalling(t *testing.T) { 131 req, err := http.NewRequestWithContext( 132 context.TODO(), 133 http.MethodHead, 134 "/", 135 nil) 136 require.NoError(t, err) 137 tests := map[string]struct { 138 input *http.Response 139 expected *Error 140 }{ 141 "API failure with HTML response": { 142 input: &http.Response{ 143 Request: req, 144 Status: "OK", 145 StatusCode: http.StatusServiceUnavailable, 146 Body: ioutil.NopCloser(strings.NewReader(`<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>`))}, 147 expected: &Error{ 148 Type: "", 149 Title: "Failed to unmarshal error body. PAPI API failed. Check details for more information.", 150 Detail: "<HTML><HEAD>...</HEAD><BODY>...</BODY></HTML>", 151 StatusCode: http.StatusServiceUnavailable, 152 }, 153 }, 154 "API failure with plain text response": { 155 input: &http.Response{ 156 Request: req, 157 Status: "OK", 158 StatusCode: http.StatusServiceUnavailable, 159 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"))}, 160 expected: &Error{ 161 Type: "", 162 StatusCode: http.StatusServiceUnavailable, 163 Title: "Failed to unmarshal error body. PAPI API failed. Check details for more information.", 164 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", 165 }, 166 }, 167 "API failure with XML response": { 168 input: &http.Response{ 169 Request: req, 170 Status: "OK", 171 StatusCode: http.StatusServiceUnavailable, 172 Body: ioutil.NopCloser(strings.NewReader(`<Root><Item id="1" name="Example" /></Root>`))}, 173 expected: &Error{ 174 Type: "", 175 StatusCode: http.StatusServiceUnavailable, 176 Title: "Failed to unmarshal error body. PAPI API failed. Check details for more information.", 177 Detail: "<Root><Item id=\"1\" name=\"Example\" /></Root>", 178 }, 179 }, 180 } 181 182 for name, test := range tests { 183 t.Run(name, func(t *testing.T) { 184 sess, _ := session.New() 185 p := papi{ 186 Session: sess, 187 } 188 assert.Equal(t, test.expected, p.Error(test.input)) 189 }) 190 } 191 }