package com.braintree.converters.utils;

import com.braintree.constants.BraintreeConstants;
import com.braintree.hybris.data.BraintreeTransactionEntryDetailData;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeTransaction;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeCustomer;
import com.braintree.hybris.data.graphql.commands.response.BraintreePaymentMethodData;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePaymentMethodSnapshot;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePayPalAccountDetails;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePaymentStatusEvent;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeTransactionAuthorizationProcessorResponse;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeMonetaryAmount;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeRefund;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeRiskData;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePaymentStatus;
import com.braintreegateway.Transaction;
import com.braintreegateway.Customer;
import com.braintreegateway.CreditCard;
import com.braintreegateway.PayPalDetails;
import com.braintreegateway.RiskData;
import de.hybris.bootstrap.annotations.UnitTest;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;

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

    private static final String ID = "ID";
    private static final String GRAPHQL_ID = "GRAPHQL_ID";
    private static final String FIRST_NAME = "FIRST_NAME";
    private static final String LAST_NAME = "LAST_NAME";
    private static final String EMAIL = "EMAIL";

    private static final String CARD_HOLDER_NAME = "CARD_HOLDER_NAME";
    private static final String CREDIT_CARD = "CREDIT_CARD";
    private static final String BIN = "BIN";
    private static final String LAST4 = "1111";
    private static final String EXPIRATION_MONTH = "01";
    private static final String EXPIRATION_YEAR = "35";
    private static final String EXPIRATION_DATE = EXPIRATION_MONTH + "/" + EXPIRATION_YEAR;
    private static final String TOKEN = "TOKEN";
    private static final String UNIQUE_NUMBER_IDENTIFIER = "UNIQUE_NUMBER_IDENTIFIER";

    private static final String AUTHORIZATION_ID = "AUTHORIZATION_ID";
    private static final String CAPTURE_ID = "CAPTURE_ID";
    private static final String CUSTOM_FIELD = "CUSTOM_FIELD";
    private static final String DEBUG_ID = "DEBUG_ID";
    private static final String REFUND_ID = "REFUND_ID";
    private static final String SELLER_PROTECTION_STATUS = "SELLER_PROTECTION_STATUS";

    private static final String MERCHANT_ACCOUNT_ID = "MERCHANT_ACCOUNT_ID";
    private static final String PROCESSOR_AUTHORIZATION_CODE = "PROCESSOR_AUTHORIZATION_CODE";
    private static final String SETTLEMENT_BATCH_ID = "SETTLEMENT_BATCH_ID";
    private static final String CVV_RESPONSE_CODE = "CVV_RESPONSE_CODE";
    private static final String SUMA = "19.99";
    private static final BigDecimal AMOUNT = new BigDecimal(SUMA);
    private static final String USD = "USD";
    private static final String AVS_ERROR_RESPONSE_CODE = "AVS_ERROR_RESPONSE_CODE";
    private static final String AVS_POSTAL_CODE_RESPONSE_CODE = "AVS_POSTAL_CODE_RESPONSE_CODE";
    private static final String AVS_STREET_ADDRESS_RESPONSE_CODE = "AVS_STREET_ADDRESS_RESPONSE_CODE";
    private static final String REFUNDED_TRANSACTION_ID = "REFUNDED_TRANSACTION_ID";
    public static final String TRANSACTION_REFUND_SIGN = "yes";
    private static final String DECISION = "DECISION";

    @Mock
    private Transaction transaction;
    @Mock
    private BrainTreeTransaction brainTreeTransaction;
    @Mock
    private Customer customer;
    @Mock
    private BrainTreeCustomer brainTreeCustomer;
    @Mock
    private CreditCard creditCard;
    @Mock
    private PayPalDetails payPalDetails;
    @Mock
    private RiskData riskData;
    @Mock
    private BraintreePaymentMethodData paymentMethod;
    @Mock
    private BrainTreePaymentMethodSnapshot methodSnapshot;
    @Mock
    private BrainTreePayPalAccountDetails payer;

    @Test
    public void shouldConvertTransactionWithCreditCard() {
        when(transaction.getCustomer()).thenReturn(customer);
        when(customer.getId()).thenReturn(ID);
        when(customer.getGraphQLId()).thenReturn(GRAPHQL_ID);
        when(customer.getFirstName()).thenReturn(FIRST_NAME);
        when(customer.getLastName()).thenReturn(LAST_NAME);
        when(customer.getEmail()).thenReturn(EMAIL);

        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.CREDIT_CARD_PAYMENT_INSTRUMENT_TYPE);

        when(transaction.getCreditCard()).thenReturn(creditCard);

        when(creditCard.getCardholderName()).thenReturn(CARD_HOLDER_NAME);
        when(creditCard.getCardType()).thenReturn(CREDIT_CARD);
        when(creditCard.getBin()).thenReturn(BIN);
        when(creditCard.getLast4()).thenReturn(LAST4);
        when(creditCard.getExpirationDate()).thenReturn(EXPIRATION_DATE);
        when(creditCard.getToken()).thenReturn(TOKEN);
        when(creditCard.getUniqueNumberIdentifier()).thenReturn(UNIQUE_NUMBER_IDENTIFIER);

        when(transaction.getMerchantAccountId()).thenReturn(MERCHANT_ACCOUNT_ID);
        when(transaction.getProcessorAuthorizationCode()).thenReturn(PROCESSOR_AUTHORIZATION_CODE);
        when(transaction.getSettlementBatchId()).thenReturn(SETTLEMENT_BATCH_ID);
        when(transaction.getStatus()).thenReturn(Transaction.Status.SUBMITTED_FOR_SETTLEMENT);
        when(transaction.getCvvResponseCode()).thenReturn(CVV_RESPONSE_CODE);
        when(transaction.getAmount()).thenReturn(AMOUNT);
        when(transaction.getCurrencyIsoCode()).thenReturn(USD);

        when(transaction.getAvsErrorResponseCode()).thenReturn(AVS_ERROR_RESPONSE_CODE);

        when(transaction.getRefundedTransactionId()).thenReturn(REFUNDED_TRANSACTION_ID);

        when(transaction.getRiskData()).thenReturn(riskData);
        when(riskData.getDecision()).thenReturn(DECISION);

        final BraintreeTransactionEntryDetailData result = BraintreeTransactionConverterUtils.convertDetails(transaction);

        assertEquals(ID, result.getCustomerInfo().getCustomerID());
        assertEquals(GRAPHQL_ID, result.getCustomerInfo().getCustomerGraphQLID());
        assertEquals(FIRST_NAME + " " + LAST_NAME, result.getCustomerInfo().getName());
        assertEquals(EMAIL, result.getCustomerInfo().getEmail());

        assertEquals(CARD_HOLDER_NAME, result.getPaymentInfo().getCardholderName());
        assertEquals(CREDIT_CARD, result.getPaymentInfo().getCardType());
        assertEquals(BIN + "******" + LAST4, result.getPaymentInfo().getCreditCardNumber());
        assertEquals(EXPIRATION_DATE, result.getPaymentInfo().getExpirationDate());
        assertEquals(BraintreeConstants.CREDIT_CARD_PAYMENT_TYPE, result.getPaymentInfo().getPaymentType());
        assertEquals(TOKEN, result.getPaymentInfo().getToken());
        assertEquals(UNIQUE_NUMBER_IDENTIFIER, result.getPaymentInfo().getUniqueNumberIdentifier());

        assertEquals(StringUtils.EMPTY, result.getTransactionInfo().getMerchant());
        assertEquals(MERCHANT_ACCOUNT_ID, result.getTransactionInfo().getMerchantAccount());
        assertEquals(PROCESSOR_AUTHORIZATION_CODE, result.getTransactionInfo().getProcessorAuthorizationCode());
        assertEquals(SETTLEMENT_BATCH_ID, result.getTransactionInfo().getSettlementBatch());
        assertEquals(Transaction.Status.SUBMITTED_FOR_SETTLEMENT.name(), result.getTransactionInfo().getStatus());
        assertEquals(CVV_RESPONSE_CODE, result.getTransactionInfo().getCvvResponse());
        assertEquals(AMOUNT + " " + USD, result.getTransactionInfo().getAmount());

        assertEquals(AVS_ERROR_RESPONSE_CODE, result.getTransactionInfo().getAvsResponse());

        assertEquals(TRANSACTION_REFUND_SIGN, result.getTransactionInfo().getRefund());

        assertEquals(DECISION, result.getTransactionInfo().getRiskDecision());
    }

    @Test
    public void shouldConvertTransactionWithPayPalPayment() {
        when(transaction.getCustomer()).thenReturn(customer);
        when(customer.getId()).thenReturn(ID);
        when(customer.getGraphQLId()).thenReturn(GRAPHQL_ID);
        when(customer.getFirstName()).thenReturn(FIRST_NAME);
        when(customer.getLastName()).thenReturn(LAST_NAME);
        when(customer.getEmail()).thenReturn(EMAIL);

        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.PAYPAL_PAYMENT_INSTRUMENT_TYPE);

        when(transaction.getPayPalDetails()).thenReturn(payPalDetails);

        when(payPalDetails.getToken()).thenReturn(TOKEN);
        when(payPalDetails.getAuthorizationId()).thenReturn(AUTHORIZATION_ID);
        when(payPalDetails.getPayeeEmail()).thenReturn(EMAIL);
        when(payPalDetails.getPayerFirstName()).thenReturn(FIRST_NAME);
        when(payPalDetails.getPayerLastName()).thenReturn(LAST_NAME);
        when(payPalDetails.getPayerId()).thenReturn(ID);
        when(payPalDetails.getPaymentId()).thenReturn(ID);
        when(payPalDetails.getCaptureId()).thenReturn(CAPTURE_ID);
        when(payPalDetails.getCustomField()).thenReturn(CUSTOM_FIELD);
        when(payPalDetails.getDebugId()).thenReturn(DEBUG_ID);
        when(payPalDetails.getRefundId()).thenReturn(REFUND_ID);
        when(payPalDetails.getSellerProtectionStatus()).thenReturn(SELLER_PROTECTION_STATUS);

        when(transaction.getMerchantAccountId()).thenReturn(MERCHANT_ACCOUNT_ID);
        when(transaction.getProcessorAuthorizationCode()).thenReturn(PROCESSOR_AUTHORIZATION_CODE);
        when(transaction.getSettlementBatchId()).thenReturn(SETTLEMENT_BATCH_ID);
        when(transaction.getStatus()).thenReturn(Transaction.Status.SUBMITTED_FOR_SETTLEMENT);
        when(transaction.getCvvResponseCode()).thenReturn(CVV_RESPONSE_CODE);
        when(transaction.getAmount()).thenReturn(AMOUNT);
        when(transaction.getCurrencyIsoCode()).thenReturn(USD);

        when(transaction.getAvsPostalCodeResponseCode()).thenReturn(AVS_POSTAL_CODE_RESPONSE_CODE);
        when(transaction.getAvsStreetAddressResponseCode()).thenReturn(AVS_STREET_ADDRESS_RESPONSE_CODE);

        when(transaction.getRefundedTransactionId()).thenReturn(REFUNDED_TRANSACTION_ID);

        when(transaction.getRiskData()).thenReturn(riskData);
        when(riskData.getDecision()).thenReturn(DECISION);

        final BraintreeTransactionEntryDetailData result = BraintreeTransactionConverterUtils.convertDetails(transaction);

        assertEquals(ID, result.getCustomerInfo().getCustomerID());
        assertEquals(GRAPHQL_ID, result.getCustomerInfo().getCustomerGraphQLID());
        assertEquals(FIRST_NAME + " " + LAST_NAME, result.getCustomerInfo().getName());
        assertEquals(EMAIL, result.getCustomerInfo().getEmail());

        assertEquals(TOKEN, result.getPaymentPayPalInfo().getToken());
        assertEquals(AUTHORIZATION_ID, result.getPaymentPayPalInfo().getAuthorizationUniqueTransactionID());
        assertEquals(EMAIL, result.getPaymentPayPalInfo().getPayeeEmail());
        assertEquals(FIRST_NAME, result.getPaymentPayPalInfo().getPayerFirstName());
        assertEquals(LAST_NAME, result.getPaymentPayPalInfo().getPayerLastName());
        assertEquals(ID, result.getPaymentPayPalInfo().getPayerID());
        assertEquals(ID, result.getPaymentPayPalInfo().getPaymentID());
        assertEquals(CAPTURE_ID, result.getPaymentPayPalInfo().getPayPalCaptureID());
        assertEquals(CUSTOM_FIELD, result.getPaymentPayPalInfo().getPayPalCustomField());
        assertEquals(DEBUG_ID, result.getPaymentPayPalInfo().getPayPalDebugID());
        assertEquals(REFUND_ID, result.getPaymentPayPalInfo().getPayPalRefundID());
        assertEquals(SELLER_PROTECTION_STATUS, result.getPaymentPayPalInfo().getPayPalSellerProtectionStatus());
        assertEquals(BraintreeConstants.PAYPAL_PAYMENT_TYPE_NAME, result.getPaymentPayPalInfo().getPaymentType());

        assertEquals(StringUtils.EMPTY, result.getTransactionInfo().getMerchant());
        assertEquals(MERCHANT_ACCOUNT_ID, result.getTransactionInfo().getMerchantAccount());
        assertEquals(PROCESSOR_AUTHORIZATION_CODE, result.getTransactionInfo().getProcessorAuthorizationCode());
        assertEquals(SETTLEMENT_BATCH_ID, result.getTransactionInfo().getSettlementBatch());
        assertEquals(Transaction.Status.SUBMITTED_FOR_SETTLEMENT.name(), result.getTransactionInfo().getStatus());
        assertEquals(CVV_RESPONSE_CODE, result.getTransactionInfo().getCvvResponse());
        assertEquals(AMOUNT + " " + USD, result.getTransactionInfo().getAmount());

        assertEquals(AVS_POSTAL_CODE_RESPONSE_CODE + " " + AVS_STREET_ADDRESS_RESPONSE_CODE, result.getTransactionInfo().getAvsResponse());

        assertEquals(TRANSACTION_REFUND_SIGN, result.getTransactionInfo().getRefund());

        assertEquals(DECISION, result.getTransactionInfo().getRiskDecision());
    }

    @Test
    public void customerInfoAndPaymentInfoAreNull() {
        when(transaction.getCustomer()).thenReturn(null);
        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.CREDIT_CARD_PAYMENT_INSTRUMENT_TYPE);
        when(transaction.getCreditCard()).thenReturn(null);
        when(transaction.getStatus()).thenReturn(Transaction.Status.SUBMITTED_FOR_SETTLEMENT);

        final BraintreeTransactionEntryDetailData result = BraintreeTransactionConverterUtils.convertDetails(transaction);

        assertNull(result.getCustomerInfo().getCustomerID());
        assertNull(result.getPaymentInfo().getToken());
    }

    @Test
    public void customerInfoAndPayPalInfoAreNull() {
        when(transaction.getCustomer()).thenReturn(null);
        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.PAYPAL_PAYMENT_INSTRUMENT_TYPE);
        when(transaction.getPayPalDetails()).thenReturn(null);
        when(transaction.getStatus()).thenReturn(Transaction.Status.SUBMITTED_FOR_SETTLEMENT);

        final BraintreeTransactionEntryDetailData result = BraintreeTransactionConverterUtils.convertDetails(transaction);

        assertNull(result.getCustomerInfo().getCustomerID());
        assertNull(result.getPaymentPayPalInfo().getToken());
    }

    @Test
    public void shouldConvertBrainTreeTransactionWithCreditCard() {
        final BrainTreePaymentStatusEvent paymentStatusEvent = mock(BrainTreePaymentStatusEvent.class);
        final List<BrainTreePaymentStatusEvent> paymentStatusEvents = Arrays.asList(paymentStatusEvent);
        final BrainTreeTransactionAuthorizationProcessorResponse processorResponse = mock(BrainTreeTransactionAuthorizationProcessorResponse.class);
        final BrainTreeMonetaryAmount monetaryAmount = mock(BrainTreeMonetaryAmount.class);
        final BrainTreeRefund brainTreeRefund = mock(BrainTreeRefund.class);
        final List<BrainTreeRefund> brainTreeRefunds = Arrays.asList(brainTreeRefund);
        final BrainTreeRiskData braintreeRiskData = mock(BrainTreeRiskData.class);

        when(brainTreeTransaction.getCustomer()).thenReturn(brainTreeCustomer);
        when(brainTreeCustomer.getLegacyId()).thenReturn(ID);
        when(brainTreeCustomer.getId()).thenReturn(GRAPHQL_ID);
        when(brainTreeCustomer.getFirstName()).thenReturn(FIRST_NAME);
        when(brainTreeCustomer.getLastName()).thenReturn(LAST_NAME);
        when(brainTreeCustomer.getEmail()).thenReturn(EMAIL);

        when(brainTreeTransaction.getPaymentMethodSnapshot()).thenReturn(methodSnapshot);
        when(methodSnapshot.get__typename()).thenReturn(BraintreeConstants.CREDIT_CARD_DETAILS);

        when(methodSnapshot.getCardholderName()).thenReturn(CARD_HOLDER_NAME);
        when(methodSnapshot.getBrandCode()).thenReturn(CREDIT_CARD);
        when(methodSnapshot.getBin()).thenReturn(BIN);
        when(methodSnapshot.getLast4()).thenReturn(LAST4);
        when(methodSnapshot.getExpirationMonth()).thenReturn(EXPIRATION_MONTH);
        when(methodSnapshot.getExpirationYear()).thenReturn(EXPIRATION_YEAR);

        when(brainTreeTransaction.getPaymentMethod()).thenReturn(paymentMethod);
        when(paymentMethod.getLegacyId()).thenReturn(ID);
        when(paymentMethod.getId()).thenReturn(GRAPHQL_ID);

        when(methodSnapshot.getUniqueNumberIdentifier()).thenReturn(UNIQUE_NUMBER_IDENTIFIER);

        when(brainTreeTransaction.getMerchantAccountId()).thenReturn(MERCHANT_ACCOUNT_ID);
        when(brainTreeTransaction.getStatus()).thenReturn(BrainTreePaymentStatus.SUBMITTED_FOR_SETTLEMENT);

        when(brainTreeTransaction.getStatusHistory()).thenReturn(paymentStatusEvents);
        when(paymentStatusEvent.get__typename()).thenReturn(BraintreeConstants.GRAPHQL_SETTLED_EVENT_TYPE);

        when(paymentStatusEvent.getProcessorResponse()).thenReturn(processorResponse);
        when(processorResponse.getLegacyCode()).thenReturn(ID);
        when(processorResponse.getCvvResponse()).thenReturn(CVV_RESPONSE_CODE);

        when(processorResponse.getAsPostalCodeResponse()).thenReturn(AVS_POSTAL_CODE_RESPONSE_CODE);
        when(processorResponse.getAvsStreetAddressResponse()).thenReturn(AVS_STREET_ADDRESS_RESPONSE_CODE);

        when(paymentStatusEvent.getSettlementBatchId()).thenReturn(SETTLEMENT_BATCH_ID);

        when(brainTreeTransaction.getAmount()).thenReturn(monetaryAmount);
        when(monetaryAmount.getValue()).thenReturn(SUMA);
        when(monetaryAmount.getCurrencyCode()).thenReturn(USD);

        when(brainTreeTransaction.getRefunds()).thenReturn(brainTreeRefunds);

        when(brainTreeTransaction.getRiskData()).thenReturn(braintreeRiskData);
        when(braintreeRiskData.getDecision()).thenReturn(DECISION);

        final BraintreeTransactionEntryDetailData result = BraintreeTransactionConverterUtils.convertDetails(brainTreeTransaction);

        assertEquals(ID, result.getCustomerInfo().getCustomerID());
        assertEquals(GRAPHQL_ID, result.getCustomerInfo().getCustomerGraphQLID());
        assertEquals(FIRST_NAME + " " + LAST_NAME, result.getCustomerInfo().getName());
        assertEquals(EMAIL, result.getCustomerInfo().getEmail());

        assertEquals(CARD_HOLDER_NAME, result.getPaymentInfo().getCardholderName());
        assertEquals(CREDIT_CARD, result.getPaymentInfo().getCardType());
        assertEquals(BIN + "******" + LAST4, result.getPaymentInfo().getCreditCardNumber());
        assertEquals(EXPIRATION_MONTH + "/" + EXPIRATION_YEAR, result.getPaymentInfo().getExpirationDate());
        assertEquals(BraintreeConstants.CREDIT_CARD_PAYMENT_TYPE, result.getPaymentInfo().getPaymentType());

        assertEquals(ID, result.getPaymentInfo().getToken());
        assertEquals(GRAPHQL_ID, result.getPaymentInfo().getGraphQLToken());

        assertEquals(UNIQUE_NUMBER_IDENTIFIER, result.getPaymentInfo().getUniqueNumberIdentifier());

        assertEquals(StringUtils.EMPTY, result.getTransactionInfo().getMerchant());
        assertEquals(MERCHANT_ACCOUNT_ID, result.getTransactionInfo().getMerchantAccount());
        assertEquals(BrainTreePaymentStatus.SUBMITTED_FOR_SETTLEMENT.name(), result.getTransactionInfo().getStatus());

        assertEquals(ID, result.getTransactionInfo().getProcessorAuthorizationCode());
        assertEquals(CVV_RESPONSE_CODE, result.getTransactionInfo().getCvvResponse());

        assertEquals(AVS_POSTAL_CODE_RESPONSE_CODE + " " + AVS_STREET_ADDRESS_RESPONSE_CODE, result.getTransactionInfo().getAvsResponse());

        assertEquals(SETTLEMENT_BATCH_ID, result.getTransactionInfo().getSettlementBatch());

        assertEquals(SUMA + " " + USD, result.getTransactionInfo().getAmount());

        assertEquals(TRANSACTION_REFUND_SIGN, result.getTransactionInfo().getRefund());

        assertEquals(DECISION, result.getTransactionInfo().getRiskDecision());

    }

    @Test
    public void shouldConvertBrainTreeTransactionWithPayPal() {
        final BrainTreePayPalAccountDetails payee = mock(BrainTreePayPalAccountDetails.class);

        when(brainTreeTransaction.getCustomer()).thenReturn(brainTreeCustomer);
        when(brainTreeCustomer.getLegacyId()).thenReturn(ID);
        when(brainTreeCustomer.getId()).thenReturn(GRAPHQL_ID);
        when(brainTreeCustomer.getFirstName()).thenReturn(FIRST_NAME);
        when(brainTreeCustomer.getLastName()).thenReturn(LAST_NAME);
        when(brainTreeCustomer.getEmail()).thenReturn(EMAIL);

        when(brainTreeTransaction.getPaymentMethodSnapshot()).thenReturn(methodSnapshot);
        when(methodSnapshot.get__typename()).thenReturn(BraintreeConstants.PAYPAL_TRANSACTION_DETAILS);

        when(brainTreeTransaction.getPaymentMethod()).thenReturn(paymentMethod);
        when(paymentMethod.getLegacyId()).thenReturn(ID);
        when(paymentMethod.getId()).thenReturn(GRAPHQL_ID);

        when(methodSnapshot.getAuthorizationId()).thenReturn(UNIQUE_NUMBER_IDENTIFIER);

        when(methodSnapshot.getPayer()).thenReturn(payer);
        when(payer.getEmail()).thenReturn(EMAIL);
        when(payer.getFirstName()).thenReturn(FIRST_NAME);
        when(payer.getLastName()).thenReturn(LAST_NAME);
        when(payer.getPayerId()).thenReturn(ID);

        when(methodSnapshot.getPayee()).thenReturn(payee);
        when(payee.getEmail()).thenReturn(EMAIL);

        when(methodSnapshot.getPaymentId()).thenReturn(ID);
        when(methodSnapshot.getCaptureId()).thenReturn(CAPTURE_ID);
        when(methodSnapshot.getCustomField()).thenReturn(CUSTOM_FIELD);
        when(methodSnapshot.getRefundId()).thenReturn(REFUND_ID);
        when(methodSnapshot.getSellerProtectionStatus()).thenReturn(SELLER_PROTECTION_STATUS);

        when(brainTreeTransaction.getMerchantAccountId()).thenReturn(MERCHANT_ACCOUNT_ID);
        when(brainTreeTransaction.getStatus()).thenReturn(BrainTreePaymentStatus.SUBMITTED_FOR_SETTLEMENT);

        final BraintreeTransactionEntryDetailData result = BraintreeTransactionConverterUtils.convertDetails(brainTreeTransaction);

        assertEquals(ID, result.getCustomerInfo().getCustomerID());
        assertEquals(GRAPHQL_ID, result.getCustomerInfo().getCustomerGraphQLID());
        assertEquals(FIRST_NAME + " " + LAST_NAME, result.getCustomerInfo().getName());
        assertEquals(EMAIL, result.getCustomerInfo().getEmail());

        assertEquals(ID, result.getPaymentPayPalInfo().getToken());
        assertEquals(GRAPHQL_ID, result.getPaymentPayPalInfo().getGraphQLToken());

        assertEquals(UNIQUE_NUMBER_IDENTIFIER, result.getPaymentPayPalInfo().getAuthorizationUniqueTransactionID());

        assertEquals(EMAIL, result.getPaymentPayPalInfo().getPayerEmail());
        assertEquals(FIRST_NAME, result.getPaymentPayPalInfo().getPayerFirstName());
        assertEquals(LAST_NAME, result.getPaymentPayPalInfo().getPayerLastName());
        assertEquals(ID, result.getPaymentPayPalInfo().getPayerID());

        assertEquals(EMAIL, result.getPaymentPayPalInfo().getPayeeEmail());

        assertEquals(ID, result.getPaymentPayPalInfo().getPaymentID());
        assertEquals(CAPTURE_ID, result.getPaymentPayPalInfo().getPayPalCaptureID());
        assertEquals(CUSTOM_FIELD, result.getPaymentPayPalInfo().getPayPalCustomField());
        assertEquals(REFUND_ID, result.getPaymentPayPalInfo().getPayPalRefundID());
        assertEquals(SELLER_PROTECTION_STATUS, result.getPaymentPayPalInfo().getPayPalSellerProtectionStatus());
        assertEquals(BraintreeConstants.PAYPAL_PAYMENT_TYPE_NAME, result.getPaymentPayPalInfo().getPaymentType());

        assertEquals(StringUtils.EMPTY, result.getTransactionInfo().getMerchant());
        assertEquals(MERCHANT_ACCOUNT_ID, result.getTransactionInfo().getMerchantAccount());
        assertEquals(BrainTreePaymentStatus.SUBMITTED_FOR_SETTLEMENT.name(), result.getTransactionInfo().getStatus());

    }

    @Test
    public void customerInfoAndPaymentInfoAndPayPalInfoAreNull() {
        when(brainTreeTransaction.getCustomer()).thenReturn(null);
        when(brainTreeTransaction.getPaymentMethodSnapshot()).thenReturn(null);
        when(brainTreeTransaction.getStatus()).thenReturn(BrainTreePaymentStatus.SUBMITTED_FOR_SETTLEMENT);

        BraintreeTransactionConverterUtils.convertDetails(brainTreeTransaction);

        verify(brainTreeTransaction).getCustomer();
        verify(brainTreeTransaction, times(2)).getPaymentMethodSnapshot();
        verify(brainTreeTransaction).getStatus();
    }

    @Test
    public void payPalInfoAndPaymentInfoAreIncorrect() {
        when(brainTreeTransaction.getPaymentMethodSnapshot()).thenReturn(methodSnapshot);
        when(methodSnapshot.get__typename()).thenReturn(BraintreeConstants.GOOGLE_PAY_ORIGIN_TYPE);
        when(brainTreeTransaction.getStatus()).thenReturn(BrainTreePaymentStatus.SUBMITTED_FOR_SETTLEMENT);

        BraintreeTransactionConverterUtils.convertDetails(brainTreeTransaction);

        verify(brainTreeTransaction, times(4)).getPaymentMethodSnapshot();
        verify(methodSnapshot, times(2)).get__typename();
        verify(brainTreeTransaction).getStatus();
    }

    @Test
    public void shouldFormedNameForFirstAndLastName() {
        final String result = BraintreeTransactionConverterUtils.formedName(FIRST_NAME, LAST_NAME);

        assertEquals(FIRST_NAME + " " + LAST_NAME, result);
    }

    @Test
    public void shouldFormedNameForFirstName() {
        final String result = BraintreeTransactionConverterUtils.formedName(FIRST_NAME, "");

        assertEquals(FIRST_NAME, result);
    }

    @Test
    public void shouldNotFormedName() {
        final String result = BraintreeTransactionConverterUtils.formedName("", "");

        assertEquals(StringUtils.EMPTY, result);
    }

    @Test
    public void shouldFormedPayPalPaymentInfoFromTransaction() {
        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.PAYPAL_PAYMENT_INSTRUMENT_TYPE);
        when(transaction.getPayPalDetails()).thenReturn(payPalDetails);
        when(payPalDetails.getPayerEmail()).thenReturn(EMAIL);

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(transaction);

        assertEquals(EMAIL, result);
        verify(transaction).getPaymentInstrumentType();
        verify(transaction).getPayPalDetails();
        verify(payPalDetails).getPayerEmail();
    }

    @Test
    public void shouldNotFormedPayPalPaymentInfoFromTransaction() {
        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.PAYPAL_PAYMENT_INSTRUMENT_TYPE);
        when(transaction.getPayPalDetails()).thenReturn(null);

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(transaction);

        assertEquals(StringUtils.EMPTY, result);
        verify(transaction).getPaymentInstrumentType();
        verify(transaction).getPayPalDetails();
    }

    @Test
    public void shouldFormedCreditCardPaymentInfoFromTransaction() {
        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.CREDIT_CARD_PAYMENT_INSTRUMENT_TYPE);
        when(transaction.getCreditCard()).thenReturn(creditCard);
        when(creditCard.getBin()).thenReturn(BIN);
        when(creditCard.getLast4()).thenReturn(LAST4);

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(transaction);

        assertEquals(BIN + "******" + LAST4, result);
        verify(transaction).getPaymentInstrumentType();
        verify(transaction).getCreditCard();
        verify(creditCard).getBin();
        verify(creditCard).getLast4();
    }

    @Test
    public void shouldNotFormedCreditCardPaymentInfoFromTransaction() {
        when(transaction.getPaymentInstrumentType()).thenReturn(BraintreeConstants.InstrumentType.CREDIT_CARD_PAYMENT_INSTRUMENT_TYPE);
        when(transaction.getCreditCard()).thenReturn(null);

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(transaction);

        assertEquals(StringUtils.EMPTY, result);
        verify(transaction).getPaymentInstrumentType();
        verify(transaction).getCreditCard();
    }

    @Test
    public void shouldReturnEmptyStringForFormedPaymentInfoForTransaction() {
        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(transaction);

        assertEquals(StringUtils.EMPTY, result);
    }

    @Test
    public void shouldFormedPayPalPaymentInfoFromBrainTreePaymentMethodSnapshot() {
        when(methodSnapshot.get__typename()).thenReturn(BraintreeConstants.PAYPAL_ACCOUNT_DETAILS);
        when(methodSnapshot.getPayer()).thenReturn(payer);
        when(payer.getEmail()).thenReturn(EMAIL);

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(methodSnapshot);

        assertEquals(EMAIL, result);
        verify(methodSnapshot).get__typename();
        verify(methodSnapshot).getPayer();
        verify(payer).getEmail();
    }

    @Test
    public void shouldNotFormedPayPalPaymentInfoFromBrainTreePaymentMethodSnapshot() {
        when(methodSnapshot.get__typename()).thenReturn(BraintreeConstants.PAYPAL_ACCOUNT_DETAILS);
        when(methodSnapshot.getPayer()).thenReturn(payer);
        when(payer.getEmail()).thenReturn(null);

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(methodSnapshot);

        assertNull(result);
        verify(methodSnapshot).get__typename();
        verify(methodSnapshot).getPayer();
        verify(payer).getEmail();
    }

    @Test
    public void shouldFormedCreditCardPaymentInfoFromBrainTreePaymentMethodSnapshot() {
        when(methodSnapshot.get__typename()).thenReturn(BraintreeConstants.CREDIT_CARD_DETAILS);
        when(methodSnapshot.getBin()).thenReturn(BIN);
        when(methodSnapshot.getLast4()).thenReturn(LAST4);

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(methodSnapshot);

        assertEquals(BIN + "******" + LAST4, result);
        verify(methodSnapshot).get__typename();
        verify(methodSnapshot).getBin();
        verify(methodSnapshot).getLast4();
    }

    @Test
    public void shouldReturnEmptyStringForFormedPaymentInfoForBrainTreePaymentMethodSnapshot() {
        BrainTreePaymentMethodSnapshot nullMethodSnapshot = null;

        final String result = BraintreeTransactionConverterUtils.formedPaymentInfo(nullMethodSnapshot);

        assertEquals(StringUtils.EMPTY, result);
    }

    @Test
    public void shouldFormedAmount() {
        final String result = BraintreeTransactionConverterUtils.formedAmount(AMOUNT, USD);

        assertEquals(SUMA + " " + USD, result);
    }

}
