@Override protected String parseResponse(HttpURLConnection connection) throws Exception { try { return super.parseResponse(connection); } catch (AuthorizationException | UnprocessableEntityException e) { if (e instanceof AuthorizationException) { String errorMessage = new ErrorWithResponse(403, e.getMessage()).getMessage(); throw new AuthorizationException(errorMessage); } else { throw new ErrorWithResponse(422, e.getMessage()); } } } }
@Test public void fromGraphQLJson_parsesGraphQLCoercionErrorsCorrectly() { String response = stringFromFixture("errors/graphql/coercion_error.json"); ErrorWithResponse errorWithResponse = ErrorWithResponse.fromGraphQLJson(response); assertEquals("Variable 'input' has coerced Null value for NonNull type 'String!'", errorWithResponse.getMessage()); assertEquals(422, errorWithResponse.getStatusCode()); }
@Test public void parcelsCorrectly() throws JSONException { ErrorWithResponse error = ErrorWithResponse.fromJson(stringFromFixture("errors/credit_card_error_response.json")); Parcel parcel = Parcel.obtain(); error.writeToParcel(parcel, 0); parcel.setDataPosition(0); ErrorWithResponse parceled = ErrorWithResponse.CREATOR.createFromParcel(parcel); assertEquals(error.getStatusCode(), parceled.getStatusCode()); assertEquals(error.getMessage(), parceled.getMessage()); assertEquals(error.getErrorResponse(), parceled.getErrorResponse()); assertEquals(error.getFieldErrors().size(), parceled.getFieldErrors().size()); } }
public static ErrorWithResponse fromJson(String json) throws JSONException { ErrorWithResponse errorWithResponse = new ErrorWithResponse(); errorWithResponse.mOriginalResponse = json; errorWithResponse.parseJson(json); return errorWithResponse; }
@Test public void fromGraphQLJson_parsesErrorsCorrectly() { String response = stringFromFixture("errors/graphql/credit_card_error.json"); ErrorWithResponse errorWithResponse = ErrorWithResponse.fromGraphQLJson(response); assertEquals("Input is invalid.", errorWithResponse.getMessage()); assertEquals(422, errorWithResponse.getStatusCode()); assertEquals("Expiration month is invalid", errorWithResponse.errorFor("creditCard").errorFor("expirationMonth").getMessage()); assertEquals("Expiration year is invalid", errorWithResponse.errorFor("creditCard").errorFor("expirationYear").getMessage()); assertEquals("CVV verification failed", errorWithResponse.errorFor("creditCard").errorFor("cvv").getMessage()); }
@Test public void constructor_parsesErrorsCorrectly() { String response = stringFromFixture("errors/credit_card_error_response.json"); ErrorWithResponse errorWithResponse = new ErrorWithResponse(422, response); assertEquals("Credit card is invalid", errorWithResponse.getMessage()); assertEquals(422, errorWithResponse.getStatusCode()); assertNull(errorWithResponse.errorFor("creditCard").errorFor("postalCode")); assertEquals("Credit card must include number, payment_method_nonce, or venmo_sdk_payment_method_code", errorWithResponse.errorFor("creditCard").errorFor("base").getMessage()); assertEquals("Credit card number is required", errorWithResponse.errorFor("creditCard").errorFor("number").getMessage()); assertEquals("Expiration year is invalid", errorWithResponse.errorFor("creditCard").errorFor("expirationYear").getMessage()); }
public ErrorWithResponse createFromParcel(Parcel source) { return new ErrorWithResponse(source); }
@Test public void constructor_handlesTopLevelErrors() { String topLevelError = stringFromFixture("errors/auth_fingerprint_error.json"); ErrorWithResponse errorWithResponse = new ErrorWithResponse(422, topLevelError); assertEquals("Authorization fingerprint is invalid", errorWithResponse.getMessage()); assertEquals(1, errorWithResponse.getFieldErrors().size()); }
@Test public void fromJson_parsesErrorsCorrectly() throws JSONException { String response = stringFromFixture("errors/credit_card_error_response.json"); ErrorWithResponse errorWithResponse = ErrorWithResponse.fromJson(response); assertEquals("Credit card is invalid", errorWithResponse.getMessage()); assertNull(errorWithResponse.errorFor("creditCard").errorFor("postalCode")); assertEquals("Credit card must include number, payment_method_nonce, or venmo_sdk_payment_method_code", errorWithResponse.errorFor("creditCard").errorFor("base").getMessage()); assertEquals("Credit card number is required", errorWithResponse.errorFor("creditCard").errorFor("number").getMessage()); assertEquals("Expiration year is invalid", errorWithResponse.errorFor("creditCard").errorFor("expirationYear").getMessage()); }
@Test public void fromGraphQLJson_doesNotBlowUpParsingBadJson() { String badJson = stringFromFixture("random_json.json"); ErrorWithResponse errorWithResponse = ErrorWithResponse.fromGraphQLJson(badJson); assertEquals("Parsing error response failed", errorWithResponse.getMessage()); }
@Test public void constructor_canHandleMultipleCategories() { String errors = stringFromFixture("errors/complex_error_response.json"); ErrorWithResponse errorWithResponse = new ErrorWithResponse(422, errors); assertEquals(3, errorWithResponse.errorFor("creditCard").getFieldErrors().size()); assertEquals("is invalid", errorWithResponse.errorFor("customer").getMessage()); assertEquals(0, errorWithResponse.errorFor("customer").getFieldErrors().size()); }
@Test public void parseResponseFailsWithUserErrors() throws Exception { String baseUrl = "http://example.com/graphql"; HttpClient httpClient = new BraintreeGraphQLHttpClient(baseUrl, TOKENIZATION_KEY); httpClient = HttpClientTestUtils.stubResponse(httpClient, 200, FixturesHelper.stringFromFixture("errors/graphql/credit_card_error.json")); HttpURLConnection connection = httpClient.init(baseUrl); try { httpClient.parseResponse(connection); fail("No exception was thrown"); } catch (ErrorWithResponse e) { assertEquals("Input is invalid.", e.getMessage()); assertNotNull(e.errorFor("creditCard")); } }
@Test(expected = JSONException.class) public void fromJson_throwsExceptionIfJsonParsingFails() throws JSONException { ErrorWithResponse.fromJson(stringFromFixture("random_json.json")); }
@Override protected String parseResponse(HttpURLConnection connection) throws Exception { String response = super.parseResponse(connection); JSONArray errors = new JSONObject(response) .optJSONArray(Keys.ERRORS); if (errors != null) { for (int i = 0; i < errors.length(); i++) { JSONObject error = errors.getJSONObject(i); JSONObject extensions = error.optJSONObject(Keys.EXTENSIONS); String message = Json.optString(error, Keys.MESSAGE, "An Unexpected Exception Occurred"); if (extensions == null) { throw new UnexpectedException(message); } if (Json.optString(extensions, Keys.LEGACY_CODE, "").equals(LegacyErrorCodes.VALIDATION_NOT_ALLOWED)) { throw new AuthorizationException(error.getString(Keys.MESSAGE)); } else if (!Json.optString(extensions, Keys.ERROR_TYPE, "").equals(ErrorTypes.USER)) { throw new UnexpectedException(message); } } throw ErrorWithResponse.fromGraphQLJson(response); } return response; } }
@Override public void onError(Exception error) { assertEquals("CVV verification failed", ((ErrorWithResponse) error).errorFor("creditCard").getFieldErrors().get(0).getMessage()); countDownLatch.countDown(); } });
@Override public void onError(Exception error) { assertTrue(error instanceof ErrorWithResponse); assertEquals(422, ((ErrorWithResponse) error).getStatusCode()); mCalled.set(true); } });
public ErrorWithResponse(int statusCode, String jsonString) { mStatusCode = statusCode; mOriginalResponse = jsonString; try { parseJson(jsonString); } catch (JSONException e) { mMessage = "Parsing error response failed"; mFieldErrors = new ArrayList<>(); } }
public static ErrorWithResponse fromGraphQLJson(String json) { ErrorWithResponse errorWithResponse = new ErrorWithResponse(); errorWithResponse.mOriginalResponse = json; errorWithResponse.mStatusCode = 422; try { JSONArray errors = new JSONObject(json).getJSONArray(Keys.ERRORS); errorWithResponse.mFieldErrors = BraintreeError.fromGraphQLJsonArray(errors); if (errorWithResponse.mFieldErrors.isEmpty()) { errorWithResponse.mMessage = errors.getJSONObject(0).getString(Keys.MESSAGE); } else { errorWithResponse.mMessage = ErrorMessages.USER; } } catch (JSONException e) { errorWithResponse.mMessage = "Parsing error response failed"; errorWithResponse.mFieldErrors = new ArrayList<>(); } return errorWithResponse; }
/** * @deprecated Android Pay is deprecated, use {@link GooglePayment} instead. For more information see the * <a href="https://developers.braintreepayments.com/guides/pay-with-google/overview">documentation</a> * * Call this method when you've received a successful FullWallet request in your activity's * {@link Activity#onActivityResult(int, int, Intent)} to get an {@link AndroidPayCardNonce} from a * {@link FullWallet}. * * @param fragment An instance of {@link BraintreeFragment}. * @param wallet a {@link FullWallet} from the Intent in {@link Activity#onActivityResult(int, int, Intent)}. * @param cart the {@link Cart} used when creating the {@link FullWallet}. */ @Deprecated public static void tokenize(BraintreeFragment fragment, FullWallet wallet, Cart cart) { try { fragment.postCallback(AndroidPayCardNonce.fromFullWallet(wallet, cart)); fragment.sendAnalyticsEvent("android-pay.nonce-received"); } catch (JSONException e) { fragment.sendAnalyticsEvent("android-pay.failed"); try { fragment.postCallback(ErrorWithResponse.fromJson(wallet.getPaymentMethodToken().getToken())); } catch (JSONException e1) { fragment.postCallback(e1); } } }
@Config(sdk = 21) @Test public void tokenize_sendGraphQLAnalyticsEventOnFailure() { BraintreeFragment fragment = new MockFragmentBuilder() .configuration(new TestConfigurationBuilder() .graphQL() .build()) .graphQLErrorResponse(ErrorWithResponse.fromGraphQLJson(stringFromFixture("errors/graphql/credit_card_error.json"))) .build(); CardBuilder cardBuilder = new CardBuilder(); TokenizationClient.tokenize(fragment, cardBuilder, new PaymentMethodNonceCallback() { @Override public void success(PaymentMethodNonce paymentMethodNonce) {} @Override public void failure(Exception exception) {} }); verify(fragment).sendAnalyticsEvent("card.graphql.tokenization.failure"); }