package com.braintree.facade.impl;

import com.braintree.command.result.BrainTreeFindCustomerResult;
import com.braintree.command.result.BrainTreePaymentDetailsResult;
import com.braintree.configuration.service.BrainTreeConfigService;
import com.braintree.converters.BrainTreePayPalAddressDataConverter;
import com.braintree.customer.service.BrainTreeCustomerAccountService;
import com.braintree.customfield.service.BraintreeCustomFieldsService;
import com.braintree.delivery.service.BraintreeDeliveryService;
import com.braintree.enums.BrainTreePaymentMethod;
import com.braintree.enums.BraintreePageType;
import com.braintree.enums.BraintreePaymentMethodLimitData;
import com.braintree.facade.BrainTreeConnectWithPayPalFacade;
import com.braintree.facade.BrainTreeUserFacade;
import com.braintree.facade.BraintreeConfigurationFacade;
import com.braintree.facade.BraintreeUrlResolutionFacade;
import com.braintree.hybris.data.BraintreeACHConfigurationData;
import com.braintree.hybris.data.BraintreeAssetsData;
import com.braintree.hybris.data.BraintreeCheckoutData;
import com.braintree.hybris.data.BraintreeConfigurationData;
import com.braintree.hybris.data.BraintreeGooglePayConfigurationData;
import com.braintree.hybris.data.BraintreeHostedFieldsConfigurationData;
import com.braintree.hybris.data.BraintreeLocalPaymentMethodData;
import com.braintree.hybris.data.BraintreePayPalConfigurationData;
import com.braintree.hybris.data.BraintreePaymentInitiator;
import com.braintree.hybris.data.BraintreePluginConfigurationData;
import com.braintree.hybris.data.BraintreeSRCConfigurationData;
import com.braintree.hybris.data.BraintreeVenmoConfigurationData;
import com.braintree.hybris.data.DropInData;
import com.braintree.hybris.data.PayPalAddressData;
import com.braintree.hybris.data.PayPalPaymentMethodData;
import com.braintree.hybris.data.PaymentMethodsLimitationData;
import com.braintree.hybris.data.SrcPaymentMethodData;
import com.braintree.method.BrainTreePaymentService;
import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.model.BraintreeLocalPaymentMethodsModel;
import com.braintree.order.service.BraintreeOrderRetrievalService;
import com.braintree.payment.info.service.BraintreePaymentInfoService;
import com.braintree.transaction.service.BrainTreeTransactionService;
import com.braintreegateway.Environment;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.acceleratorservices.uiexperience.UiExperienceService;
import de.hybris.platform.catalog.CatalogVersionService;
import de.hybris.platform.catalog.model.CatalogVersionModel;
import de.hybris.platform.commercefacades.order.CartFacade;
import de.hybris.platform.commercefacades.order.data.CCPaymentInfoData;
import de.hybris.platform.commercefacades.order.data.CartData;
import de.hybris.platform.commercefacades.order.data.OrderData;
import de.hybris.platform.commerceservices.customer.CustomerAccountService;
import de.hybris.platform.commerceservices.order.CommerceCheckoutService;
import de.hybris.platform.commerceservices.service.data.CommerceCheckoutParameter;
import de.hybris.platform.commerceservices.service.data.CommerceOrderParameter;
import de.hybris.platform.commerceservices.service.data.CommerceOrderResult;
import de.hybris.platform.commerceservices.strategies.CheckoutCustomerStrategy;
import de.hybris.platform.core.model.c2l.CountryModel;
import de.hybris.platform.core.model.c2l.CurrencyModel;
import de.hybris.platform.core.model.media.MediaModel;
import de.hybris.platform.core.model.order.CartModel;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.core.model.order.payment.CreditCardPaymentInfoModel;
import de.hybris.platform.core.model.user.AddressModel;
import de.hybris.platform.core.model.user.CustomerModel;
import de.hybris.platform.order.CartService;
import de.hybris.platform.order.InvalidCartException;
import de.hybris.platform.ordermanagementfacades.payment.data.PaymentTransactionEntryData;
import de.hybris.platform.payment.AdapterException;
import de.hybris.platform.payment.dto.TransactionStatus;
import de.hybris.platform.payment.enums.PaymentTransactionType;
import de.hybris.platform.payment.model.PaymentTransactionEntryModel;
import de.hybris.platform.servicelayer.dto.converter.Converter;
import de.hybris.platform.servicelayer.i18n.I18NService;
import de.hybris.platform.servicelayer.media.MediaService;
import de.hybris.platform.servicelayer.model.ModelService;
import de.hybris.platform.servicelayer.session.Session;
import de.hybris.platform.servicelayer.session.SessionService;
import de.hybris.platform.servicelayer.user.UserService;
import de.hybris.platform.util.PriceValue;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@UnitTest
@RunWith(MockitoJUnitRunner.class)
public class DefaultBrainTreeCheckoutFacadeTest {

    private static final String INTENT = "intent";
    private static final String SHIPS_FROM_POSTAL_CODE = "ships";
    private static final String CUSTOMER_FIELD_KEY = "customerFieldKey";
    private static final String CUSTOMER_FIELD_VALUE = "customFieldValue";
    private static final String SECURITY_CODE = "securityCode";
    private static final String PAYMENT_INFO_ID = "paymentInfoId";
    private static final String PAYMENT_METHOD_NONCE = "paymentMethodNonce";
    private static final String USD = "USD";
    private static final String GOOGLE_IMG_CODE = "googlePayMark";
    private static final Map<String, String> CUSTOM_FIELDS = Collections.emptyMap();
    private static final String SUBSCRIPTION_ID = "subscriptionId";
    private static final String ACCEPTED = "ACCEPTED";
    private static final String ZERO = "ZERO";
    private static final String EMAIL = "EMAIL";
    private static final String REVIEW = "REVIEW";
    private static final BigDecimal AMOUNT = BigDecimal.valueOf(100);
    private static final String CVV_NONCE = "cvvNonce";
    private static final String CLIENT_TOKEN = "clientToken";
    private static final String BRAINTREE_CUSTOMER_ID = "braintreeCustomerId";
    private static final String ENVIRONMENT_TYPE = "environmentType";
    private static final String ENDPOINT_URL = "endpointURL";
    private static final String USER_ACTION = "userAction";
    private static final int EXPIRATION_PAYMENT_REMOVAL_RESTRICTION = 1;
    private static final int ORDERS_WITH_EXPIERED_TRANSACTIONS = 0;
    private static final String DISABLE_FUNDING = "disableFunding";
    private static final String SRC_SDK_URL = "srcSdkURL";
    private static final String SRC_IMG_URL = "srcImgUrl";
    private static final Double TOTAL_PRICE = 20.23;
    private static final Double SUBTOTAL = 18.94;
    private static final String PAYPAL_PAYMENT_PROVIDER = "PayPalAccount";
    private static final String EN_US_LOCALE = "en_US";
    private static final String INVALID_LOCAL = "invalidLocal";
    private static final String NOT_SUPPORTED_LOCALE = "not_supported";
    private static final String COUNTRY_US = "US";
    private static final String CONNECT_SCRIPT = "connectScript";
    private static final String CONNECT_SCOPES = "connectScopes";
    private static final String CONNECT_RESPONSE_TYPE = "connectResponseType";
    private static final String DEVELOPMENT = "development";
    private static final String HTTP_TEST_CONNECT = "http/test/connect";
    private static final String CONNECT = "/connect";
    private static final String DISPLAY_NAME = "displayName";
    private static final String LOCAL_PAYMENT_METHODS_FALLBACK_URL_EXPECTED = "/localPaymentMethods/fallback?currency=USD";

    @Mock
    private MediaService mediaService;
    @Mock
    private CheckoutCustomerStrategy checkoutCustomerStrategy;
    @Mock
    private DefaultBrainTreePaymentFacade brainTreePaymentFacade;
    @Mock
    private CommerceCheckoutService commerceCheckoutService;
    @Mock
    private Converter<BrainTreePaymentInfoModel, CCPaymentInfoData> brainTreePaymentInfoConverter;
    @Mock
    private BrainTreePaymentService brainTreePaymentService;
    @Mock
    private CatalogVersionService catalogVersionService;
    @Mock
    private CustomerAccountService customerAccountService;
    @Mock
    private CartService cartService;
    @Mock
    private BrainTreeConfigService brainTreeConfigService;
    @Mock
    private BraintreeConfigurationFacade braintreeConfigurationFacade;
    @Mock
    private BraintreeOrderRetrievalService orderRetrievalService;
    @Mock
    private ModelService modelService;
    @Mock
    private I18NService i18NService;
    @Mock
    private Converter<OrderModel, OrderData> orderConverter;
    @Mock
    private Converter<PaymentTransactionEntryModel, PaymentTransactionEntryData> ordermanagementEntryConverter;
    @Mock
    private BrainTreePayPalAddressDataConverter payPalAddressDataConverter;
    @Mock
    private CartFacade cartFacade;
    @Mock
    private UserService userService;
    @Mock
    private BrainTreeUserFacade brainTreeUserFacade;
    @Mock
    private BraintreeUrlResolutionFacade braintreeUrlResolutionFacade;

    @Mock
    private Converter<BraintreeLocalPaymentMethodsModel, BraintreeLocalPaymentMethodData> brainTreeLocalPaymentsConverter;
    @Mock
    private Converter<CreditCardPaymentInfoModel, CCPaymentInfoData> creditCardPaymentInfoConverter;
    @Mock
    private Converter<PaymentTransactionEntryModel, PaymentTransactionEntryData> ordermanagementPaymentTransactionEntryConverter;

    @Mock
    private UiExperienceService uiExperienceService;
    @Mock
    private BraintreeCustomFieldsService customFieldsService;
    @Mock
    private SessionService sessionService;
    @Mock
    private Session session;
    @Mock
    private BrainTreeTransactionService brainTreeTransactionService;
    @Mock
    private BraintreeDeliveryService braintreeDeliveryService;
    @Mock
    private BraintreePaymentInfoService braintreePaymentInfoService;
    @Mock
    private BrainTreeConnectWithPayPalFacade connectWithPayPalFacade;
    @Mock
    private BrainTreeCustomerAccountService brainTreeCustomerAccountService;

    @Spy
    @InjectMocks
    private DefaultBrainTreeCheckoutFacade unit;

    @Mock
    private CartModel cart;
    @Mock
    private OrderModel order;
    @Mock
    private BrainTreePaymentInfoModel paymentInfo;
    @Mock
    private CreditCardPaymentInfoModel creditCardPaymentInfo;
    @Mock
    private CustomerModel user;
    @Mock
    private PaymentTransactionEntryModel transactionEntryModel;
    @Mock
    private PaymentTransactionEntryModel authorizationTransactionEntryModel;
    @Mock
    private CurrencyModel currencyModel;
    @Mock
    private AddressModel addressModel;
    @Mock
    private CountryModel countryModel;
    @Mock
    private PriceValue priceValue;
    @Mock
    private BraintreeLocalPaymentMethodsModel localPaymentMethodsModel;
    @Mock
    private MediaModel mediaModel;
    @Mock
    private CatalogVersionModel catalogVersionModel;
    @Mock
    private CommerceOrderResult orderResult;
    @Captor
    ArgumentCaptor<CommerceOrderParameter> parameterCaptor;

    @Test
    public void shouldSetIntentToSessionCart() {
        when(brainTreeConfigService.getIntent()).thenReturn(INTENT);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);

        unit.storeIntentToCart();

        verify(paymentInfo).setPayPalIntent(INTENT);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldSetIntentToGivenCart() {
        when(brainTreeConfigService.getIntent()).thenReturn(INTENT);
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);

        unit.storeIntentToCart(cart);

        verify(paymentInfo).setPayPalIntent(INTENT);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldSetShipFromPostalCodeToSessionCart() {
        when(cartService.getSessionCart()).thenReturn(cart);
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);

        unit.storeShipsFromPostalCodeToCart(SHIPS_FROM_POSTAL_CODE);

        verify(paymentInfo).setShipsFromPostalCode(SHIPS_FROM_POSTAL_CODE);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldSetShipFromPostalCodeToGivenCart() {
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);

        unit.storeShipsFromPostalCodeToCart(SHIPS_FROM_POSTAL_CODE, cart);

        verify(paymentInfo).setShipsFromPostalCode(SHIPS_FROM_POSTAL_CODE);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldSetCustomFieldsToSessionCart() {
        Map<String, String> customFields = Map.of(CUSTOMER_FIELD_KEY, CUSTOMER_FIELD_VALUE);

        when(cartService.getSessionCart()).thenReturn(cart);
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);

        unit.storeCustomFieldsToCart(customFields);

        verify(paymentInfo).setCustomFields(customFields);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldSetCustomFieldsToGivenCart() {
        Map<String, String> customFields = Map.of(CUSTOMER_FIELD_KEY, CUSTOMER_FIELD_VALUE);

        when(cart.getPaymentInfo()).thenReturn(paymentInfo);

        unit.storeCustomFieldsToCart(customFields, cart);

        verify(paymentInfo).setCustomFields(customFields);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldAuthorizePayment() {
        when(transactionEntryModel.getTransactionStatus()).thenReturn(TransactionStatus.ACCEPTED.name());
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(brainTreeTransactionService.createAuthorizationTransaction(any(CommerceOrderParameter.class))).thenReturn(transactionEntryModel);

        when(cart.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.isSaved()).thenReturn(false);

        boolean result = unit.authorizePayment(SECURITY_CODE);

        assertTrue(result);
    }

    @Test
    public void shouldAuthorizePaymentWhenAuthorizationStatusReview() {
        when(transactionEntryModel.getTransactionStatus()).thenReturn(TransactionStatus.REVIEW.name());
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(brainTreeTransactionService.createAuthorizationTransaction(any(CommerceOrderParameter.class))).thenReturn(transactionEntryModel);

        when(cart.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.isSaved()).thenReturn(false);

        boolean result = unit.authorizePayment(SECURITY_CODE);

        assertTrue(result);
    }

    @Test
    public void shouldReturnFalseWhenCreateAuthorizationThrowException() {
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(brainTreeTransactionService.createAuthorizationTransaction(any(CommerceOrderParameter.class))).thenThrow(AdapterException.class);

        when(cart.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.isSaved()).thenReturn(false);

        boolean result = unit.authorizePayment(SECURITY_CODE);

        assertFalse(result);
    }

    @Test
    public void shouldVerify3DSDuringAuthorizePayment() {
        when(customFieldsService.getDefaultCustomFieldsMap()).thenReturn(CUSTOM_FIELDS);
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(brainTreeTransactionService.createAuthorizationTransaction(any())).thenReturn(transactionEntryModel);
        when(transactionEntryModel.getTransactionStatus()).thenReturn(ACCEPTED);

        when(cart.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.isSaved()).thenReturn(true);
        when(paymentInfo.getNonce()).thenReturn(PAYMENT_METHOD_NONCE);

        boolean result = unit.authorizePayment(SECURITY_CODE);

        assertTrue(result);
        verify(brainTreePaymentFacade).verifyThreeDSForSelectedPayment(paymentInfo, PAYMENT_METHOD_NONCE);
    }

    @Test
    public void shouldCallSuperAuthorizePaymentWhenCreditCardPaymentInfoModelUsed() {
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(checkoutCustomerStrategy.getCurrentUserForCheckout()).thenReturn(user);
        when(commerceCheckoutService.authorizePayment(any(CommerceCheckoutParameter.class))).thenReturn(transactionEntryModel);

        when(cart.getPaymentInfo()).thenReturn(creditCardPaymentInfo);
        when(cart.getUser()).thenReturn(user);
        when(creditCardPaymentInfo.getSubscriptionId()).thenReturn(SUBSCRIPTION_ID);
        when(transactionEntryModel.getTransactionStatus()).thenReturn(ACCEPTED);

        boolean result = unit.authorizePayment(SECURITY_CODE);

        assertTrue(result);
    }

    @Test
    public void shouldAuthorizePaymentByGivenCartWhenStatusAccepted() {
        when(brainTreeTransactionService.createAuthorizationTransaction(any(CommerceOrderParameter.class))).thenReturn(transactionEntryModel);
        when(customFieldsService.getDefaultCustomFieldsMap()).thenReturn(CUSTOM_FIELDS);
        when(transactionEntryModel.getTransactionStatus()).thenReturn(ACCEPTED);

        boolean result = unit.authorizePayment(cart);

        assertTrue(result);
    }

    @Test
    public void shouldAuthorizePaymentByGivenCartWhenStatusReview() {
        when(brainTreeTransactionService.createAuthorizationTransaction(any(CommerceOrderParameter.class))).thenReturn(transactionEntryModel);
        when(customFieldsService.getDefaultCustomFieldsMap()).thenReturn(CUSTOM_FIELDS);
        when(transactionEntryModel.getTransactionStatus()).thenReturn(REVIEW);

        boolean result = unit.authorizePayment(cart);

        assertTrue(result);
    }

    @Test
    public void shouldCapturePaymentByGivenOrderAndAmount() {
        final PaymentTransactionEntryData data = new PaymentTransactionEntryData();

        when(brainTreeTransactionService.createAuthorizationTransactionForCapture(any(CommerceOrderParameter.class), any(Boolean.class))).thenReturn(transactionEntryModel);
        when(ordermanagementPaymentTransactionEntryConverter.convert(transactionEntryModel)).thenReturn(data);

        final PaymentTransactionEntryData result = unit.capturePayment(order, AMOUNT, authorizationTransactionEntryModel, false);

        assertEquals(data, result);
        verify(brainTreeTransactionService).createAuthorizationTransactionForCapture(parameterCaptor.capture(), any(Boolean.class));
        CommerceOrderParameter parameter = parameterCaptor.getValue();
        assertEquals(order, parameter.getOrder());
        assertEquals(AMOUNT, parameter.getAmount());
        assertEquals(authorizationTransactionEntryModel, parameter.getTransactionEntry());
        assertEquals(BraintreePaymentInitiator.UNSCHEDULED, parameter.getPaymentInitiator());
    }

    @Test
    public void shouldReturnPaymentInfoFromSessionCart() {
        CCPaymentInfoData data = new CCPaymentInfoData();
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(brainTreePaymentInfoConverter.convert(paymentInfo)).thenReturn(data);

        when(cart.getPaymentInfo()).thenReturn(paymentInfo);

        CCPaymentInfoData result = unit.getPaymentDetails();

        assertEquals(data, result);
    }

    @Test
    public void shouldReturnNullIfNoSessionCart() {
        when(cartFacade.hasSessionCart()).thenReturn(false);

        CCPaymentInfoData result = unit.getPaymentDetails();

        assertNull(result);
    }

    @Test
    public void shouldUseDefaultImplementationIfCreditCardPaymentInfoModel() {
        CCPaymentInfoData data = new CCPaymentInfoData();
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(creditCardPaymentInfoConverter.convert(creditCardPaymentInfo)).thenReturn(data);

        when(cart.getPaymentInfo()).thenReturn(creditCardPaymentInfo);

        CCPaymentInfoData result = unit.getPaymentDetails();

        assertEquals(data, result);
    }

    @Test
    public void shouldReturnFalseIfCurrentUserIsNotTheCartUser() {
        CustomerModel userModel = mock(CustomerModel.class);

        boolean result = unit.setPaymentDetails(PAYMENT_INFO_ID, PAYMENT_METHOD_NONCE, StringUtils.EMPTY, false);

        assertFalse(result);
    }

    @Test
    public void shouldSetNonceForPaymentInfoAndSavePaymentInfo() {
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(cart.getUser()).thenReturn(user);
        when(checkoutCustomerStrategy.getCurrentUserForCheckout()).thenReturn(user);
        BrainTreePaymentInfoModel paymentInfoModel = mock(BrainTreePaymentInfoModel.class);
        when(brainTreePaymentService.completeCreateSubscriptionWithCvvVerification(user, PAYMENT_INFO_ID, CVV_NONCE))
                .thenReturn(paymentInfoModel);

        boolean result = unit.setPaymentDetails(PAYMENT_INFO_ID, PAYMENT_METHOD_NONCE, CVV_NONCE, false);

        assertTrue(result);

        verify(brainTreePaymentService).completeCreateSubscriptionWithCvvVerification(user, PAYMENT_INFO_ID, CVV_NONCE);
        verify(paymentInfoModel).setNonce(PAYMENT_METHOD_NONCE);
        verify(modelService).save(paymentInfoModel);
    }

    @Test
    public void shouldSetPaymentDetailsByPaymentId() {
        when(checkoutCustomerStrategy.getCurrentUserForCheckout()).thenReturn(user);
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(cart.getUser()).thenReturn(user);
        when(brainTreePaymentService.completeCreateSubscription(user, PAYMENT_INFO_ID)).thenReturn(paymentInfo);

        boolean result = unit.setPaymentDetails(PAYMENT_INFO_ID);

        assertTrue(result);

        verify(brainTreePaymentService).completeCreateSubscription(user, PAYMENT_INFO_ID);
    }

    @Test
    public void shouldNoSetPaymentDetailsByPaymentIdIfCurrentUserIsNotTheCartUser() {
        boolean result = unit.setPaymentDetails(PAYMENT_INFO_ID);

        assertFalse(result);

        verify(brainTreePaymentService, never()).completeCreateSubscription(user, PAYMENT_INFO_ID);
    }

    @Test
    public void shouldGenerateClientTokenWithoutBraintreeCustomerId() {
        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreePaymentService.generateClientToken(StringUtils.EMPTY)).thenReturn(CLIENT_TOKEN);

        String result = unit.generateClientToken(false);

        assertEquals(CLIENT_TOKEN, result);
        verify(brainTreePaymentService).generateClientToken(StringUtils.EMPTY);
    }

    @Test
    public void shouldGenerateClientTokenWithBraintreeCustomerId() {
        when(userService.getCurrentUser()).thenReturn(user);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);
        when(brainTreePaymentService.generateClientToken(BRAINTREE_CUSTOMER_ID)).thenReturn(CLIENT_TOKEN);

        String result = unit.generateClientToken(true);

        assertEquals(CLIENT_TOKEN, result);
        verify(brainTreePaymentService).generateClientToken(BRAINTREE_CUSTOMER_ID);
    }

    @Test
    public void shouldReturnEmptyStringIfAdapterExceptionOccur() {
        when(userService.getCurrentUser()).thenReturn(user);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);
        when(brainTreePaymentService.generateClientToken(BRAINTREE_CUSTOMER_ID)).thenThrow(new AdapterException());

        String result = unit.generateClientToken(true);

        assertEquals(StringUtils.EMPTY, result);
        verify(brainTreePaymentService).generateClientToken(BRAINTREE_CUSTOMER_ID);
    }

    @Test
    public void shouldReturnBraintreeCheckoutData() {
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult(false);
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(CLIENT_TOKEN).when(unit).generateClientToken(false);

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(brainTreeConfigService.getEnvironmentTypeName()).thenReturn(ENVIRONMENT_TYPE);
        when(brainTreeConfigService.getEndpointURL()).thenReturn(ENDPOINT_URL);
        when(brainTreeConfigService.getUserAction()).thenReturn(USER_ACTION);
        when(brainTreeConfigService.getBrainTreeDisplayName()).thenReturn(DISPLAY_NAME);
        when(brainTreeConfigService.getRestrictionPaymentMethodRemovalExpiration()).thenReturn(EXPIRATION_PAYMENT_REMOVAL_RESTRICTION);
        when(brainTreeConfigService.isRestrictionPaymentMethodRemovalEnable()).thenReturn(true);
        when(orderRetrievalService.countOrdersWithExpiredTransactionsByCustomer(user, EXPIRATION_PAYMENT_REMOVAL_RESTRICTION))
                .thenReturn(ORDERS_WITH_EXPIERED_TRANSACTIONS);
        when(brainTreeConfigService.isPayPalEnabled()).thenReturn(true);
        when(brainTreeConfigService.isPayPalExpressEnabled()).thenReturn(true);
        when(brainTreeConfigService.getDisableFunding(pageType)).thenReturn(DISABLE_FUNDING);
        when(brainTreeConfigService.getBrainTreeLocale()).thenReturn(StringUtils.EMPTY);
        when(brainTreeConfigService.getSrcSdkUrl()).thenReturn(SRC_SDK_URL);
        when(brainTreeConfigService.getSrcImgUrl()).thenReturn(SRC_IMG_URL);
        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(sessionService.getAttribute("user")).thenReturn(user);

        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);

        when(braintreePaymentInfoService.countPaymentInfoByCustomerIdAndPaymentProvider(BRAINTREE_CUSTOMER_ID, BrainTreePaymentMethod.ANDROIDPAYCARD)).thenReturn(10);

        when(userService.getCurrentUser()).thenReturn(user);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertNotNull(result);
        assertFalse(result.getEnableShippingAddress());

        assertNotNull(result.getDropIn());
        DropInData dropInDataResult = result.getDropIn();
        assertFalse(dropInDataResult.getIsLimitedDeletePaymentMethods());

        assertNotNull(result.getPayPalPaymentMethod());
        PayPalPaymentMethodData payPalDataResult = result.getPayPalPaymentMethod();
        assertTrue(payPalDataResult.getPayPalStandardEnabled());
        assertTrue(payPalDataResult.getPayPalExpressEnabled());
        assertEquals(DISABLE_FUNDING, payPalDataResult.getDisableFunding());
        assertFalse(payPalDataResult.getShouldShowShippingAddressMessage());

        assertNotNull(result.getConfigurationData());
        BraintreeConfigurationData configurationDataResult = result.getConfigurationData();
        assertEquals(USD, configurationDataResult.getCurrency());
        assertEquals(ENVIRONMENT_TYPE, configurationDataResult.getEnvironment());
        assertEquals(locale.toString(), configurationDataResult.getLocale());
        assertEquals(ENDPOINT_URL, configurationDataResult.getEndpointURL());
        assertEquals(USER_ACTION, configurationDataResult.getUserAction());
        assertEquals(DISPLAY_NAME, configurationDataResult.getDbaName());
        assertEquals(CLIENT_TOKEN, configurationDataResult.getClient_id());

        assertNotNull(result.getSrcPaymentMethod());
        SrcPaymentMethodData srcPaymentMethodDataResult = result.getSrcPaymentMethod();
        assertEquals(SRC_SDK_URL, srcPaymentMethodDataResult.getSrcSdkUrl());
        assertEquals(SRC_IMG_URL, srcPaymentMethodDataResult.getSrcImgUrl());

        assertNotNull(result.getPaymentMethodsLimitation());
        PaymentMethodsLimitationData paymentMethodsLimitationDataResult = result.getPaymentMethodsLimitation();
        assertFalse(paymentMethodsLimitationDataResult.isPayPalOnLimit());
        assertTrue(paymentMethodsLimitationDataResult.isSRCOnLimit());
        assertFalse(paymentMethodsLimitationDataResult.isVenmoOnLimit());
        assertTrue(paymentMethodsLimitationDataResult.isGooglePayOnLimit());
        assertFalse(paymentMethodsLimitationDataResult.isUsBankAccountOnLimit());
        assertFalse(paymentMethodsLimitationDataResult.isCreditCardOnLimit());

    }

    @Test
    public void shouldReturnTrueWhenAllowedPaymentsLimited() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        pluginConfigurationData.getPayPalConfigurationData().setSavedPayPalAccountLimit(BraintreePaymentMethodLimitData.THREE);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(userService.getUserForUID(any())).thenReturn(user);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);
        when(braintreePaymentInfoService.countPaymentInfoByCustomerIdAndPaymentProvider(BRAINTREE_CUSTOMER_ID, BrainTreePaymentMethod.PAYPALACCOUNT)).thenReturn(3);

        assertTrue(unit.isPayPalLimitedDuringConnect(EMAIL));
    }

    @Test
    public void shouldReturnFalseWhenMaxAllowedPaymentsUnlimited() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        assertFalse(unit.isPayPalLimitedDuringConnect(EMAIL));
    }

    @Test
    public void shouldReturnFalseWhenBraintreeCustomerIdIsNull() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        pluginConfigurationData.getPayPalConfigurationData().setSavedPayPalAccountLimit(BraintreePaymentMethodLimitData.THREE);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(userService.getUserForUID(any())).thenReturn(user);

        assertFalse(unit.isPayPalLimitedDuringConnect(EMAIL));
    }

    @Test
    public void shouldReturnBraintreeCheckoutDataWithSessionCartData() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        CartData cartData = new CartData();
        cartData.setDeliveryOrderGroups(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(cartData).when(unit).getCheckoutCart();

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(cartService.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);

        when(userService.getCurrentUser()).thenReturn(user);

        when(cart.getTotalPrice()).thenReturn(TOTAL_PRICE);
        when(cart.getSubtotal()).thenReturn(SUBTOTAL);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertFalse(result.getEnableShippingAddress());
        assertEquals(TOTAL_PRICE, result.getAmount());
        assertEquals(SUBTOTAL, result.getSubtotal());
    }

    @Test
    public void shouldSetChangePaymentButtonFalseInBraintreeCheckoutDataWhenPageTypeAccount() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        brainTreeFindCustomerResult.setPaymentMethods(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.ACCOUNT;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertFalse(result.getPayPalPaymentMethod().getShouldRenderPayPalChangePaymentButton());
    }

    @Test
    public void shouldSetChangePaymentButtonFalseInBraintreeCheckoutDataWhenCurrentUserGuest() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        brainTreeFindCustomerResult.setPaymentMethods(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertFalse(result.getPayPalPaymentMethod().getShouldRenderPayPalChangePaymentButton());
    }

    @Test
    public void shouldSetChangePaymentButtonFalseInBraintreeCheckoutDataWhenCurrentUserDoesNotHaveBraintreeCustomerId() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        brainTreeFindCustomerResult.setPaymentMethods(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(false);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertFalse(result.getPayPalPaymentMethod().getShouldRenderPayPalChangePaymentButton());
    }

    @Test
    public void shouldSetChangePaymentButtonFalseInBraintreeCheckoutDataWhenDropInEnabled() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        brainTreeFindCustomerResult.setPaymentMethods(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(true);

        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertFalse(result.getPayPalPaymentMethod().getShouldRenderPayPalChangePaymentButton());
    }

    @Test
    public void shouldSetChangePaymentButtonFalseInBraintreeCheckoutDataWhenChangePaymentButtonDisabled() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        brainTreeFindCustomerResult.setPaymentMethods(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(false);

        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertFalse(result.getPayPalPaymentMethod().getShouldRenderPayPalChangePaymentButton());
    }

    @Test
    public void shouldSetChangePaymentButtonFalseInBraintreeCheckoutDataWhenThereAreNoPayPalPaymentMethods() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        brainTreeFindCustomerResult.setPaymentMethods(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertFalse(result.getPayPalPaymentMethod().getShouldRenderPayPalChangePaymentButton());
    }

    @Test
    public void shouldSetChangePaymentButtonTrueInBraintreeCheckoutDataWhenAllConditionsAreMet() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();
        brainTreePaymentDetailsResult.setPaymentProvider(PAYPAL_PAYMENT_PROVIDER);
        brainTreeFindCustomerResult.setPaymentMethods(List.of(brainTreePaymentDetailsResult));

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertTrue(result.getPayPalPaymentMethod().getShouldRenderPayPalChangePaymentButton());
    }

    @Test
    public void shouldSetBraintreeLocaleInBraintreeCheckoutDataForENLocale() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();
        brainTreePaymentDetailsResult.setPaymentProvider(PAYPAL_PAYMENT_PROVIDER);
        brainTreeFindCustomerResult.setPaymentMethods(List.of(brainTreePaymentDetailsResult));

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(brainTreeConfigService.getBrainTreeLocale()).thenReturn(EN_US_LOCALE);

        when(userService.getCurrentUser()).thenReturn(user);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(EN_US_LOCALE, result.getConfigurationData().getLocale());
    }

    @Test
    public void shouldSetDefaultBraintreeLocaleInBraintreeCheckoutDataIfInputParameterInvalid() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();
        brainTreePaymentDetailsResult.setPaymentProvider(PAYPAL_PAYMENT_PROVIDER);
        brainTreeFindCustomerResult.setPaymentMethods(List.of(brainTreePaymentDetailsResult));

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(brainTreeConfigService.getBrainTreeLocale()).thenReturn(INVALID_LOCAL);

        when(userService.getCurrentUser()).thenReturn(user);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(EN_US_LOCALE, result.getConfigurationData().getLocale());
    }

    public void shouldSetDefaultBraintreeLocaleInBraintreeCheckoutDataIfInputParameterNotSupported() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();
        brainTreePaymentDetailsResult.setPaymentProvider(PAYPAL_PAYMENT_PROVIDER);
        brainTreeFindCustomerResult.setPaymentMethods(List.of(brainTreePaymentDetailsResult));

        BraintreePageType pageType = BraintreePageType.OTHER;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(brainTreeConfigService.getBrainTreeLocale()).thenReturn(NOT_SUPPORTED_LOCALE);

        when(userService.getCurrentUser()).thenReturn(user);
        when(user.getAddresses()).thenReturn(Collections.EMPTY_LIST);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(EN_US_LOCALE, result.getConfigurationData().getLocale());
    }

    @Test
    public void shouldSetShippingAddressOverrideInBraintreeCheckoutForDefaultAddressAndCartPage() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        PayPalAddressData payPalAddressData = new PayPalAddressData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();
        brainTreePaymentDetailsResult.setPaymentProvider(PAYPAL_PAYMENT_PROVIDER);
        brainTreeFindCustomerResult.setPaymentMethods(List.of(brainTreePaymentDetailsResult));
        CartData cartData = new CartData();
        cartData.setDeliveryOrderGroups(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.CART;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(cartData).when(unit).getCheckoutCart();

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(cartService.hasSessionCart()).thenReturn(true);
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(braintreeDeliveryService.countDeliveryPriceForOrderAndCountyCode(cart, COUNTRY_US)).thenReturn(priceValue);
        when(payPalAddressDataConverter.convert(addressModel)).thenReturn(payPalAddressData);

        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);
        when(user.getDefaultShipmentAddress()).thenReturn(addressModel);
        when(addressModel.getCountry()).thenReturn(countryModel);
        when(countryModel.getIsocode()).thenReturn(COUNTRY_US);
        when(priceValue.getValue()).thenReturn(TOTAL_PRICE);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(payPalAddressData, result.getShippingAddressOverride());
        assertEquals(TOTAL_PRICE, result.getDeliveryAmount());
    }

    @Test
    public void shouldSetShippingAddressOverrideInBraintreeCheckoutForLastSavedAddressAndMinicartPage() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        PayPalAddressData payPalAddressData = new PayPalAddressData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();
        brainTreePaymentDetailsResult.setPaymentProvider(PAYPAL_PAYMENT_PROVIDER);
        brainTreeFindCustomerResult.setPaymentMethods(List.of(brainTreePaymentDetailsResult));
        CartData cartData = new CartData();
        cartData.setDeliveryOrderGroups(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.MINICART;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(cartData).when(unit).getCheckoutCart();

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(cartService.hasSessionCart()).thenReturn(true);
        when(cartFacade.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);
        when(braintreeDeliveryService.countDeliveryPriceForOrderAndCountyCode(cart, COUNTRY_US)).thenReturn(priceValue);
        when(payPalAddressDataConverter.convert(addressModel)).thenReturn(payPalAddressData);

        when(user.getAddresses()).thenReturn(List.of(addressModel));
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);
        when(addressModel.getCountry()).thenReturn(countryModel);
        when(countryModel.getIsocode()).thenReturn(COUNTRY_US);
        when(priceValue.getValue()).thenReturn(TOTAL_PRICE);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(payPalAddressData, result.getShippingAddressOverride());
        assertEquals(TOTAL_PRICE, result.getDeliveryAmount());
    }

    @Test
    public void shouldNotSetShippingAddressOverrideInBraintreeCheckoutIfNoAddressPresentForCartPage() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        PayPalAddressData payPalAddressData = new PayPalAddressData();
        BrainTreeFindCustomerResult brainTreeFindCustomerResult = new BrainTreeFindCustomerResult();
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();
        brainTreePaymentDetailsResult.setPaymentProvider(PAYPAL_PAYMENT_PROVIDER);
        brainTreeFindCustomerResult.setPaymentMethods(List.of(brainTreePaymentDetailsResult));
        CartData cartData = new CartData();
        cartData.setDeliveryOrderGroups(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.CART;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(cartData).when(unit).getCheckoutCart();

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);

        when(brainTreeConfigService.isChangePaymentMethodButtonEnabled()).thenReturn(true);
        when(brainTreeConfigService.isDropInEnabled()).thenReturn(false);

        when(cartService.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(userService.getCurrentUser()).thenReturn(user);
        when(brainTreeUserFacade.isAnonymousUser()).thenReturn(false);
        when(brainTreeUserFacade.isCurrentUserHasBrainTreeCustomerId()).thenReturn(true);
        when(brainTreeUserFacade.findBrainTreeCustomer(BRAINTREE_CUSTOMER_ID)).thenReturn(brainTreeFindCustomerResult);

        when(user.getAddresses()).thenReturn(Collections.EMPTY_LIST);
        when(user.getBraintreeCustomerId()).thenReturn(BRAINTREE_CUSTOMER_ID);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertNull(result.getShippingAddressOverride());
        assertTrue(result.getPayPalPaymentMethod().getShouldShowShippingAddressMessage());
    }

    @Test
    public void shouldSetShippingAddressOverrideAndLocalPaymentDataInBraintreeCheckoutIfMarkPage() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BraintreeLocalPaymentMethodData localPaymentMethodData = new BraintreeLocalPaymentMethodData();
        PayPalAddressData payPalAddressData = new PayPalAddressData();
        CartData cartData = new CartData();
        cartData.setDeliveryOrderGroups(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.MARK;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(cartData).when(unit).getCheckoutCart();

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(brainTreePaymentFacade.getLocalPaymentMethods()).thenReturn(List.of(localPaymentMethodsModel));
        when(brainTreeLocalPaymentsConverter.convertAll(List.of(localPaymentMethodsModel))).thenReturn(List.of(localPaymentMethodData));
        when(braintreeUrlResolutionFacade.buildReturnUrl(LOCAL_PAYMENT_METHODS_FALLBACK_URL_EXPECTED)).thenReturn(LOCAL_PAYMENT_METHODS_FALLBACK_URL_EXPECTED);
        when(cartService.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(userService.getCurrentUser()).thenReturn(user);
        when(payPalAddressDataConverter.convert(addressModel)).thenReturn(payPalAddressData);

        when(cart.getDeliveryAddress()).thenReturn(addressModel);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(payPalAddressData, result.getShippingAddressOverride());
        assertEquals(localPaymentMethodData, result.getLocalPaymentMethod().getLocalPaymentMethods().get(0));
        assertEquals(LOCAL_PAYMENT_METHODS_FALLBACK_URL_EXPECTED, result.getLocalPaymentMethod().getLpmFallbackReturnUrl());
    }

    @Test
    public void shouldSetShippingAddressOverrideInBraintreeCheckoutIfCartPage() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        BraintreeLocalPaymentMethodData localPaymentMethodData = new BraintreeLocalPaymentMethodData();
        PayPalAddressData payPalAddressData = new PayPalAddressData();
        CartData cartData = new CartData();
        cartData.setDeliveryOrderGroups(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.CART;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(cartData).when(unit).getCheckoutCart();

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(cartService.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(userService.getCurrentUser()).thenReturn(user);
        when(payPalAddressDataConverter.convert(addressModel)).thenReturn(payPalAddressData);

        when(cart.getDeliveryAddress()).thenReturn(addressModel);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(payPalAddressData, result.getShippingAddressOverride());
    }

    @Test
    public void shouldSetShippingAddressOverrideInBraintreeCheckoutIfMinicartPage() {
        BraintreePluginConfigurationData pluginConfigurationData = preparePluginConfigurationData();
        PayPalAddressData payPalAddressData = new PayPalAddressData();
        CartData cartData = new CartData();
        cartData.setDeliveryOrderGroups(Collections.EMPTY_LIST);

        BraintreePageType pageType = BraintreePageType.MINICART;
        Currency currency = Currency.getInstance(USD);
        Locale locale = Locale.US;

        doReturn(cartData).when(unit).getCheckoutCart();

        when(i18NService.getCurrentJavaCurrency()).thenReturn(currency);
        when(i18NService.getCurrentLocale()).thenReturn(locale);

        when(braintreeConfigurationFacade.getBraintreePluginConfigurationData()).thenReturn(pluginConfigurationData);
        when(cartService.hasSessionCart()).thenReturn(true);
        when(cartService.getSessionCart()).thenReturn(cart);
        when(userService.getCurrentUser()).thenReturn(user);
        when(payPalAddressDataConverter.convert(addressModel)).thenReturn(payPalAddressData);

        when(cart.getDeliveryAddress()).thenReturn(addressModel);

        BraintreeCheckoutData result = unit.getBraintreeCheckoutData(pageType);

        assertEquals(payPalAddressData, result.getShippingAddressOverride());
    }

    @Test
    public void shouldReturnBraintreeAssets() {
        when(catalogVersionService.getSessionCatalogVersions()).thenReturn(List.of(catalogVersionModel));
        when(mediaService.getMedia(catalogVersionModel, GOOGLE_IMG_CODE)).thenReturn(mediaModel);

        BraintreeAssetsData result = unit.getBraintreeAssets();

        assertNotNull(result);
        verify(mediaModel).getDownloadURL();
    }

    @Test
    public void shouldReturnTrueIfPayPalPaymentProvider() {
        when(order.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.getProperty(anyString())).thenReturn(BrainTreePaymentMethod.PAYPALACCOUNT.getCode());

        Boolean result = unit.isPayPalCheckout(order);

        assertTrue(result);
    }

    @Test
    public void shouldReturnFalseIfNotPayPalPaymentProvider() {
        when(order.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.getProperty(anyString())).thenReturn(BrainTreePaymentMethod.VISACHECKOUTCARD.getCode());

        Boolean result = unit.isPayPalCheckout(order);

        assertFalse(result);
    }

    @Test
    public void shouldReturnFalseIfNoPaymentProvider() {
        when(order.getPaymentInfo()).thenReturn(paymentInfo);

        Boolean result = unit.isPayPalCheckout(order);

        assertFalse(result);
    }

    @Test
    public void shouldPlaceOrderByCart() throws InvalidCartException {
        when(orderResult.getOrder()).thenReturn(order);
        when(commerceCheckoutService.placeOrder(any(CommerceCheckoutParameter.class))).thenReturn(orderResult);

        unit.placeOrderByCart(cart);

        verify(orderConverter).convert(order);
    }

    @Test
    public void shouldReturnNullWhenPlaceOrderByCart() throws InvalidCartException {
        OrderData result = unit.placeOrderByCart(null);

        assertNull(result);
    }

    @Test
    public void shouldPlaceOrderForLocalPaymentReversed() throws InvalidCartException {
        doNothing().when(unit).beforePlaceOrder(cart);
        when(commerceCheckoutService.placeOrder(any(CommerceCheckoutParameter.class))).thenReturn(orderResult);
        when(orderResult.getOrder()).thenReturn(order);

        unit.placeOrderForLocalPaymentReversed(cart);

        verify(unit).afterPlaceOrder(cart, order);
    }

    @Test
    public void shouldProcessLocalPaymentReversedWebhook() {
        when(brainTreeTransactionService.createTransactionEntryForLocalPaymentReversed(cart, PaymentTransactionType.AUTHORIZATION)).thenReturn(transactionEntryModel);
        when(brainTreeTransactionService.createTransactionEntryForLocalPaymentReversed(cart, PaymentTransactionType.CAPTURE)).thenReturn(transactionEntryModel);
        when(brainTreeTransactionService.createTransactionEntryForLocalPaymentReversed(cart, PaymentTransactionType.REFUND_FOLLOW_ON)).thenReturn(transactionEntryModel);

        unit.processLocalPaymentReversedWebhook(cart);

        verify(brainTreeTransactionService).createPaymentTransactionForLocalPaymentReversed(cart, Arrays.asList(transactionEntryModel, transactionEntryModel, transactionEntryModel));
    }

    @Test
    public void shouldReturnPayPalConfigurationDataForConnectWithPayPalButtonTest() {
        when(brainTreeConfigService.getClientID()).thenReturn(CLIENT_TOKEN);
        when(brainTreeConfigService.getPayPalConnectScript()).thenReturn(CONNECT_SCRIPT);
        when(brainTreeConfigService.getPayPalConnectScopes()).thenReturn(CONNECT_SCOPES);
        when(brainTreeConfigService.getPayPalConnectResponseType()).thenReturn(CONNECT_RESPONSE_TYPE);
        when(braintreeUrlResolutionFacade.buildReturnUrl(CONNECT)).thenReturn(HTTP_TEST_CONNECT);
        when(brainTreeConfigService.getEnvironmentType()).thenReturn(Environment.DEVELOPMENT);

        BraintreeCheckoutData result = unit.getBraintreeConfigurationDataForConnectWithPayPalButton();

        assertEquals(CLIENT_TOKEN, result.getConfigurationData().getClient_id());
        assertEquals(CONNECT_SCRIPT, result.getConfigurationData().getPayPalConnectScript());
        assertEquals(CONNECT_SCOPES, result.getConfigurationData().getPayPalConnectScopes());
        assertEquals(CONNECT_RESPONSE_TYPE, result.getConfigurationData().getPayPalConnectResponseType());
        assertEquals(HTTP_TEST_CONNECT, result.getConfigurationData().getPayPalConnectReturnUrl());
        assertEquals(DEVELOPMENT, result.getConfigurationData().getEnvironment());
    }

    @Test
    public void shouldStoreIntentInPaymentInfoInBeforePlaceOrder(){
        when(brainTreeConfigService.getIntent()).thenReturn(INTENT);
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.getCustomFields()).thenReturn(CUSTOM_FIELDS);
        when(paymentInfo.getShipsFromPostalCode()).thenReturn(SHIPS_FROM_POSTAL_CODE);

        unit.beforePlaceOrder(cart);

        verify(paymentInfo).setPayPalIntent(INTENT);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldStoreShipFromPostalCodeInPaymentInfoInBeforePlaceOrder(){
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);
        when(cart.getDeliveryAddress()).thenReturn(addressModel);
        when(addressModel.getPostalcode()).thenReturn(SHIPS_FROM_POSTAL_CODE);
        when(paymentInfo.getCustomFields()).thenReturn(CUSTOM_FIELDS);

        unit.beforePlaceOrder(cart);

        verify(paymentInfo).setShipsFromPostalCode(SHIPS_FROM_POSTAL_CODE);
        verify(modelService, times(2)).save(paymentInfo);
    }

    @Test
    public void shouldStoreCustomFieldsInPaymentInfoInBeforePlaceOrder(){
        when(customFieldsService.getDefaultCustomFieldsMap()).thenReturn(CUSTOM_FIELDS);
        when(cart.getPaymentInfo()).thenReturn(paymentInfo);
        when(paymentInfo.getShipsFromPostalCode()).thenReturn(SHIPS_FROM_POSTAL_CODE);
        when(paymentInfo.getCustomFields()).thenReturn(null);

        unit.beforePlaceOrder(cart);

        verify(paymentInfo).setCustomFields(CUSTOM_FIELDS);
        verify(modelService, times(2)).save(paymentInfo);
    }

    @Test
    public void shouldUpdatePaymentMethodNonce(){
        when(checkoutCustomerStrategy.getCurrentUserForCheckout()).thenReturn(user);
        when(brainTreeCustomerAccountService.getBrainTreePaymentInfoForCode(user, PAYMENT_INFO_ID)).thenReturn(paymentInfo);

        boolean result = unit.updatePaymentMethodNonce(PAYMENT_INFO_ID, PAYMENT_METHOD_NONCE);

        assertTrue(result);
        verify(paymentInfo).setNonce(PAYMENT_METHOD_NONCE);
        verify(modelService).save(paymentInfo);
    }

    @Test
    public void shouldNotUpdatePaymentMethodNonceIfNoPaymentMethodWithGivenIdExist(){
        when(checkoutCustomerStrategy.getCurrentUserForCheckout()).thenReturn(user);

        boolean result = unit.updatePaymentMethodNonce(PAYMENT_INFO_ID, PAYMENT_METHOD_NONCE);

        assertFalse(result);
    }

    private static BraintreePluginConfigurationData preparePluginConfigurationData() {
        BraintreePluginConfigurationData pluginConfigurationData = new BraintreePluginConfigurationData();
        BraintreePayPalConfigurationData payPalConfigurationData = new BraintreePayPalConfigurationData();
        payPalConfigurationData.setPayPalEnabled(true);
        payPalConfigurationData.setSavedPayPalAccountLimit(BraintreePaymentMethodLimitData.UNLIMITED);
        BraintreeSRCConfigurationData srcConfigurationData = new BraintreeSRCConfigurationData();
        srcConfigurationData.setEnabled(false);
        srcConfigurationData.setSavedSRCAccountLimit(BraintreePaymentMethodLimitData.THREE);
        BraintreeVenmoConfigurationData venmoConfigurationData = new BraintreeVenmoConfigurationData();
        venmoConfigurationData.setEnabled(true);
        venmoConfigurationData.setSavedVenmoAccountLimit(BraintreePaymentMethodLimitData.THREE);
        BraintreeGooglePayConfigurationData googlePayConfigurationData = new BraintreeGooglePayConfigurationData();
        googlePayConfigurationData.setEnabled(true);
        googlePayConfigurationData.setSavedGooglePayAccountLimit(BraintreePaymentMethodLimitData.THREE);
        BraintreeACHConfigurationData achConfigurationData = new BraintreeACHConfigurationData();
        achConfigurationData.setEnabled(true);
        achConfigurationData.setSavedACHAccountLimit(BraintreePaymentMethodLimitData.THREE);
        BraintreeHostedFieldsConfigurationData hostedFieldsConfigurationData = new BraintreeHostedFieldsConfigurationData();
        hostedFieldsConfigurationData.setEnabled(true);
        hostedFieldsConfigurationData.setSavedCardAccountLimit(BraintreePaymentMethodLimitData.THREE);
        pluginConfigurationData.setAchConfigurationData(achConfigurationData);
        pluginConfigurationData.setGooglePayConfigurationData(googlePayConfigurationData);
        pluginConfigurationData.setHostedFieldsConfigurationData(hostedFieldsConfigurationData);
        pluginConfigurationData.setVenmoConfigurationData(venmoConfigurationData);
        pluginConfigurationData.setSrcConfigurationData(srcConfigurationData);
        pluginConfigurationData.setPayPalConfigurationData(payPalConfigurationData);
        return pluginConfigurationData;
    }

}
