@Config(sdk = 21) @Test public void deletePaymentMethodNonce_postToGraphQL() throws Exception { Authorization authorization = Authorization.fromString(stringFromFixture("client_token.json")); BraintreeFragment fragment = new MockFragmentBuilder() .authorization(authorization) .graphQLSuccessResponse("Success") .sessionId("test-session-id") .integration("test-integration") .build(); PaymentMethod.deletePaymentMethod(fragment, mCardNonce); ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); verify(fragment.getGraphQLHttpClient()).post(captor.capture(), any(HttpResponseCallback.class)); JSONObject graphQlRequest = new JSONObject(captor.getValue()); assertEquals(GraphQLQueryHelper.getQuery(RuntimeEnvironment.application, R.raw.delete_payment_method_mutation), graphQlRequest.getString(GraphQLConstants.Keys.QUERY)); JSONObject metadata = graphQlRequest.getJSONObject("clientSdkMetadata"); assertEquals(mCardNonce.getNonce(), graphQlRequest.getJSONObject("variables") .getJSONObject("input").getString("singleUseTokenId")); assertEquals("DeletePaymentMethodFromSingleUseToken", graphQlRequest .getString(GraphQLConstants.Keys.OPERATION_NAME)); assertEquals("test-integration", metadata.getString("integration")); assertEquals("test-session-id", metadata.getString("sessionId")); assertEquals("client", metadata.getString("source")); }
@Test public void getLaunchIntent_containsCorrectVenmoExtras() throws JSONException, InvalidArgumentException { Configuration configuration = getConfigurationFromFixture(); BraintreeFragment fragment = new MockFragmentBuilder() .authorization(Authorization.fromString(stringFromFixture("client_token.json"))) .configuration(configuration) .sessionId("session-id") .build(); when(fragment.getIntegrationType()).thenReturn("custom"); Intent intent = Venmo.getLaunchIntent(configuration.getPayWithVenmo(), configuration.getPayWithVenmo().getMerchantId(), fragment); assertEquals(new ComponentName("com.venmo", "com.venmo.controller.SetupMerchantActivity"), intent.getComponent()); assertEquals("merchant-id", intent.getStringExtra(Venmo.EXTRA_MERCHANT_ID)); assertEquals("access-token", intent.getStringExtra(Venmo.EXTRA_ACCESS_TOKEN)); assertEquals("environment", intent.getStringExtra(Venmo.EXTRA_ENVIRONMENT)); JSONObject braintreeData = new JSONObject(intent.getStringExtra(Venmo.EXTRA_BRAINTREE_DATA)); JSONObject meta = braintreeData.getJSONObject("_meta"); assertNotNull(meta); assertEquals("session-id", meta.getString("sessionId")); assertEquals("custom", meta.getString("integration")); assertEquals(BuildConfig.VERSION_NAME, meta.getString("version")); assertEquals("android", meta.getString("platform")); }
@Test public void deletePaymentMethodNonce_withApiBelowLollipop_doesNotPostToGraphQL() throws InvalidArgumentException { Authorization authorization = Authorization.fromString(stringFromFixture("client_token.json")); BraintreeFragment fragment = new MockFragmentBuilder() .authorization(authorization) .graphQLSuccessResponse("Success") .sessionId("test-session-id") .integration("test-integration") .build(); PaymentMethod.deletePaymentMethod(fragment, mCardNonce); ArgumentCaptor<Exception> captor = ArgumentCaptor.forClass(Exception.class); verify(fragment).postCallback(captor.capture()); assertTrue(captor.getValue() instanceof BraintreeException); assertEquals("Payment Method Nonce deletion is not supported for API < 21", captor.getValue().getMessage()); verifyZeroInteractions(fragment.getGraphQLHttpClient()); } }
@Test public void onActivityResult_withFailedVaultCall_postsCallbackToErrorListener() throws InvalidArgumentException { Configuration configuration = getConfigurationFromFixture(); Authorization clientToken = Authorization.fromString(stringFromFixture("base_64_client_token.txt")); disableSignatureVerification(); BraintreeFragment fragment = new MockFragmentBuilder() .context(VenmoInstalledContextFactory.venmoInstalledContext(true, RuntimeEnvironment.application)) .configuration(configuration) .authorization(clientToken) .sessionId("session-id") .errorResponse(new AuthorizationException("Bad fingerprint")) .build(); ArgumentCaptor<Exception> responseCaptor = ArgumentCaptor.forClass(Exception.class); Venmo.authorizeAccount(fragment, true); Intent responseIntent = new Intent() .putExtra(Venmo.EXTRA_PAYMENT_METHOD_NONCE, "nonce"); Venmo.onActivityResult(fragment, Activity.RESULT_OK, responseIntent); verify(fragment).postCallback(responseCaptor.capture()); Exception exception = responseCaptor.getValue(); assertTrue(exception instanceof AuthorizationException); assertEquals("Bad fingerprint", exception.getMessage()); }
@Test public void onActivityResult_doesNotPerformRequestIfTokenizationKeyUsed() throws NoSuchAlgorithmException, InvalidArgumentException { Configuration configuration = getConfigurationFromFixture(); mockStatic(TokenizationClient.class); BraintreeFragment fragment = new MockFragmentBuilder() .context(VenmoInstalledContextFactory.venmoInstalledContext(true, RuntimeEnvironment.application)) .configuration(configuration) .authorization(Authorization.fromString("sandbox_tk_abcd")) .sessionId("another-session-id") .build(); Venmo.authorizeAccount(fragment, true); Venmo.onActivityResult(fragment, Activity.RESULT_OK, new Intent()); verifyStatic(times(0)); TokenizationClient.tokenize(eq(fragment), any(VenmoAccountBuilder.class), any(PaymentMethodNonceCallback.class)); }
@Test public void onActivityResult_withSuccessfulVaultCall_returnsVenmoAccountNonce() throws InvalidArgumentException { Configuration configuration = getConfigurationFromFixture(); Authorization clientToken = Authorization.fromString(stringFromFixture("base_64_client_token.txt")); disableSignatureVerification(); BraintreeFragment fragment = new MockFragmentBuilder() .context(VenmoInstalledContextFactory.venmoInstalledContext(true, RuntimeEnvironment.application)) .configuration(configuration) .authorization(clientToken) .sessionId("session-id") .successResponse(stringFromFixture("payment_methods/venmo_account_response.json")) .build(); Venmo.authorizeAccount(fragment, true); ArgumentCaptor<PaymentMethodNonce> responseCaptor = ArgumentCaptor.forClass(PaymentMethodNonce.class); Intent responseIntent = new Intent() .putExtra(Venmo.EXTRA_PAYMENT_METHOD_NONCE, "nonce"); Venmo.onActivityResult(fragment, Activity.RESULT_OK, responseIntent); verify(fragment).postCallback(responseCaptor.capture()); PaymentMethodNonce capturedNonce = responseCaptor.getValue(); assertTrue(capturedNonce instanceof VenmoAccountNonce); VenmoAccountNonce venmoAccountNonce = (VenmoAccountNonce) capturedNonce; assertEquals("Venmo", venmoAccountNonce.getTypeLabel()); assertEquals("fake-venmo-nonce", venmoAccountNonce.getNonce()); assertEquals("venmojoe", venmoAccountNonce.getUsername()); }
@Test public void onActivityResult_performsVaultRequestIfRequestPersisted() throws InvalidArgumentException, NoSuchAlgorithmException { Configuration configuration = getConfigurationFromFixture(); Authorization clientToken = Authorization.fromString(stringFromFixture("base_64_client_token.txt")); disableSignatureVerification(); BraintreeFragment fragment = new MockFragmentBuilder() .context(VenmoInstalledContextFactory.venmoInstalledContext(true, RuntimeEnvironment.application)) .configuration(configuration) .authorization(clientToken) .sessionId("session-id") .build(); Venmo.authorizeAccount(fragment, true); mockStatic(TokenizationClient.class); Venmo.onActivityResult(fragment, Activity.RESULT_OK, new Intent()); verifyStatic(); TokenizationClient.tokenize(eq(fragment), any(VenmoAccountBuilder.class), any(PaymentMethodNonceCallback.class)); }
@Test public void performAppSwitch_persistsFalseIfTokenizationKeyUsed() throws InvalidArgumentException { Configuration configuration = getConfigurationFromFixture(); Authorization tokenizationkey = Authorization.fromString("sandbox_tk_abcd"); disableSignatureVerification(); BraintreeFragment fragment = new MockFragmentBuilder() .context(VenmoInstalledContextFactory.venmoInstalledContext(true, RuntimeEnvironment.application)) .configuration(configuration) .authorization(tokenizationkey) .sessionId("session-id") .build(); Venmo.authorizeAccount(fragment, true); SharedPreferences prefs = SharedPreferencesHelper.getSharedPreferences(fragment.getApplicationContext()); assertFalse(prefs.getBoolean("com.braintreepayments.api.Venmo.VAULT_VENMO_KEY", true)); }
@Test public void onActivityResult_withSuccessfulVaultCall_sendsAnalyticsEvent() throws InvalidArgumentException { Configuration configuration = getConfigurationFromFixture(); Authorization clientToken = Authorization.fromString(stringFromFixture("base_64_client_token.txt")); disableSignatureVerification(); BraintreeFragment fragment = new MockFragmentBuilder() .context(VenmoInstalledContextFactory.venmoInstalledContext(true, RuntimeEnvironment.application)) .configuration(configuration) .authorization(clientToken) .sessionId("session-id") .successResponse(stringFromFixture("payment_methods/venmo_account_response.json")) .build(); Venmo.authorizeAccount(fragment, true); Intent responseIntent = new Intent() .putExtra(Venmo.EXTRA_PAYMENT_METHOD_NONCE, "nonce"); Venmo.onActivityResult(fragment, Activity.RESULT_OK, responseIntent); verify(fragment).sendAnalyticsEvent(endsWith("pay-with-venmo.vault.success")); }
@Test public void onActivityResult_withFailedVaultCall_sendsAnalyticsEvent() throws InvalidArgumentException { Configuration configuration = getConfigurationFromFixture(); Authorization clientToken = Authorization.fromString(stringFromFixture("base_64_client_token.txt")); disableSignatureVerification(); BraintreeFragment fragment = new MockFragmentBuilder() .context(VenmoInstalledContextFactory.venmoInstalledContext(true, RuntimeEnvironment.application)) .configuration(configuration) .authorization(clientToken) .sessionId("session-id") .errorResponse(new AuthorizationException("Bad fingerprint")) .build(); Venmo.authorizeAccount(fragment, true); Intent responseIntent = new Intent() .putExtra(Venmo.EXTRA_PAYMENT_METHOD_NONCE, "nonce"); Venmo.onActivityResult(fragment, Activity.RESULT_OK, responseIntent); verify(fragment).sendAnalyticsEvent(endsWith("pay-with-venmo.vault.failed")); }