package com.braintree.populators;

import com.braintree.hybris.data.BraintreeTransactionEntryCustomerData;
import com.braintree.hybris.data.BraintreeTransactionEntryData;
import com.braintree.hybris.data.BraintreeTransactionEntryDetailData;
import com.braintree.hybris.data.BraintreeTransactionEntryPayPalData;
import com.braintree.hybris.data.BraintreeTransactionEntryPaymentData;
import com.braintree.hybris.data.BraintreeTransactionOriginEntryData;
import com.braintree.model.BrainTreeTransactionDetailModel;
import de.hybris.bootstrap.annotations.UnitTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

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

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

    private static final String MERCHANT_ACCOUNT = "MerchantAccount";
    private static final String ENTRY_DATA_ID = "entryDataID";
    private static final String ENTRY_DATA_TYPE = "entryDataType";
    private static final String PAY_PAL_PAYMENT_TYPE = "PayPalPaymentType";
    private static final String MERCHANT = "Merchant";
    private static final String TRANSACTION_STATUS = "TransactionStatus";
    private static final String TRANSACTION_DATE = "TransactionDate";
    private static final String SETTLEMENT_BATCH = "SettlementBatch";
    private static final String AVS_RESPONSE = "AvsResponse";
    private static final String CVV_RESPONSE = "CvvResponse";
    private static final String PROCESSOR_AUTHORIZATION_CODE = "ProcessorAuthorizationCode";
    private static final String AMOUNT = "100";
    private static final String REFUND = "Refund";
    private static final String RISK_DECISION = "RiskDecision";
    private static final String CARDHOLDER_NAME = "CardholderName";
    private static final String CARD_TYPE = "CardType";
    private static final String CREDIT_CARD_NUMBER = "CreditCardNumber";
    private static final String EXPIRATION_DATE = "ExpirationDate";
    private static final String TOKEN = "Token";
    private static final String UNIQUE_NUMBER_IDENTIFIER = "UniqueNumberIdentifier";
    private static final String AUTHORIZATION_UNIQUE_TRANSACTION_ID = "AuthorizationUniqueTransactionID";
    private static final String PAYEE_EMAIL = "PayeeEmail";
    private static final String PAYER_EMAIL = "PayerEmail";
    private static final String PAYER_FIRST_NAME = "PayerFirstName";
    private static final String PAYER_LAST_NAME = "PayerLastName";
    private static final String PAYMENT_ID = "PaymentID";
    private static final String PAY_PAL_CAPTURE_ID = "PayPalCaptureID";
    private static final String PAY_PAL_CUSTOM_FIELD = "PayPalCustomField";
    private static final String PAY_PAL_DEBUG_ID = "PayPalDebugID";
    private static final String PAY_PAL_REFUND_ID = "PayPalRefundID";
    private static final String PAY_PAL_SELLER_PROTECTION_STATUS = "PayPalSellerProtectionStatus";
    private static final String PAY_PAL_TOKEN = "PayPalToken";
    private static final String CUSTOMER_EMAIL = "CustomerEmail";
    public static final String CUSTOMER_ID = "CustomerId";
    private static final String CUSTOMER_NAME = "CustomerName";

    @InjectMocks
    private BraintreeTransactionDetailPopulator unit;
    @Mock
    private BraintreeTransactionEntryData entryData;
    @Mock
    private BraintreeTransactionEntryDetailData entryDetailData;
    @Mock
    private BraintreeTransactionEntryPayPalData entryPayPalData;
    @Mock
    private BraintreeTransactionOriginEntryData transactionOriginEntryData;
    @Mock
    private BraintreeTransactionEntryPaymentData transactionEntryPaymentData;
    @Mock
    private BraintreeTransactionEntryCustomerData entryCustomerData;

    @Before
    public void setUp(){
        when(entryData.getId()).thenReturn(ENTRY_DATA_ID);
        when(entryData.getType()).thenReturn(ENTRY_DATA_TYPE);
        when(entryData.getDetails()).thenReturn(entryDetailData);
        when(entryDetailData.getPaymentPayPalInfo()).thenReturn(entryPayPalData);
        when(entryPayPalData.getPaymentType()).thenReturn(PAY_PAL_PAYMENT_TYPE);
        when(entryDetailData.getTransactionInfo()).thenReturn(transactionOriginEntryData);
        when(transactionOriginEntryData.getMerchant()).thenReturn(MERCHANT);
        when(transactionOriginEntryData.getMerchantAccount()).thenReturn(MERCHANT_ACCOUNT);
        when(transactionOriginEntryData.getStatus()).thenReturn(TRANSACTION_STATUS);
        when(transactionOriginEntryData.getTransactionDate()).thenReturn(TRANSACTION_DATE);
        when(transactionOriginEntryData.getSettlementBatch()).thenReturn(SETTLEMENT_BATCH);
        when(transactionOriginEntryData.getAvsResponse()).thenReturn(AVS_RESPONSE);
        when(transactionOriginEntryData.getCvvResponse()).thenReturn(CVV_RESPONSE);
        when(transactionOriginEntryData.getProcessorAuthorizationCode()).thenReturn(PROCESSOR_AUTHORIZATION_CODE);
        when(transactionOriginEntryData.getAmount()).thenReturn(AMOUNT);
        when(transactionOriginEntryData.getRefund()).thenReturn(REFUND);
        when(transactionOriginEntryData.getRiskDecision()).thenReturn(RISK_DECISION);
        when(entryDetailData.getPaymentInfo()).thenReturn(transactionEntryPaymentData);
        when(transactionEntryPaymentData.getCardholderName()).thenReturn(CARDHOLDER_NAME);
        when(transactionEntryPaymentData.getCardType()).thenReturn(CARD_TYPE);
        when(transactionEntryPaymentData.getCreditCardNumber()).thenReturn(CREDIT_CARD_NUMBER);
        when(transactionEntryPaymentData.getExpirationDate()).thenReturn(EXPIRATION_DATE);
        when(transactionEntryPaymentData.getToken()).thenReturn(TOKEN);
        when(transactionEntryPaymentData.getUniqueNumberIdentifier()).thenReturn(UNIQUE_NUMBER_IDENTIFIER);
        when(entryDetailData.getPaymentPayPalInfo()).thenReturn(entryPayPalData);
        when(entryPayPalData.getAuthorizationUniqueTransactionID()).thenReturn(AUTHORIZATION_UNIQUE_TRANSACTION_ID);
        when(entryPayPalData.getPayeeEmail()).thenReturn(PAYEE_EMAIL);
        when(entryPayPalData.getPayerEmail()).thenReturn(PAYER_EMAIL);
        when(entryPayPalData.getPayerFirstName()).thenReturn(PAYER_FIRST_NAME);
        when(entryPayPalData.getPayerLastName()).thenReturn(PAYER_LAST_NAME);
        when(entryPayPalData.getPaymentID()).thenReturn(PAYMENT_ID);
        when(entryPayPalData.getPayPalCaptureID()).thenReturn(PAY_PAL_CAPTURE_ID);
        when(entryPayPalData.getPayPalCustomField()).thenReturn(PAY_PAL_CUSTOM_FIELD);
        when(entryPayPalData.getPayPalDebugID()).thenReturn(PAY_PAL_DEBUG_ID);
        when(entryPayPalData.getPayPalRefundID()).thenReturn(PAY_PAL_REFUND_ID);
        when(entryPayPalData.getPayPalSellerProtectionStatus()).thenReturn(PAY_PAL_SELLER_PROTECTION_STATUS);
        when(entryPayPalData.getToken()).thenReturn(PAY_PAL_TOKEN);
        when(entryDetailData.getCustomerInfo()).thenReturn(entryCustomerData);
        when(entryCustomerData.getEmail()).thenReturn(CUSTOMER_EMAIL);
        when(entryCustomerData.getCustomerID()).thenReturn(CUSTOMER_ID);
        when(entryCustomerData.getName()).thenReturn(CUSTOMER_NAME);
    }

    @Test
    public void shouldPopulateBraintreeTransactionEntryToBrainTreeTransactionDetailWhenPayPalTest() {
        BrainTreeTransactionDetailModel brainTreeTransactionDetailModel = new BrainTreeTransactionDetailModel();

        unit.populate(entryData, brainTreeTransactionDetailModel);

        assertEquals(ENTRY_DATA_ID, brainTreeTransactionDetailModel.getId());
        assertEquals(ENTRY_DATA_TYPE, brainTreeTransactionDetailModel.getType());
        assertEquals(PAY_PAL_PAYMENT_TYPE, brainTreeTransactionDetailModel.getPaymentType());
        assertEquals(MERCHANT, brainTreeTransactionDetailModel.getMerchant());
        assertEquals(MERCHANT_ACCOUNT, brainTreeTransactionDetailModel.getMerchantAccount());
        assertEquals(TRANSACTION_STATUS, brainTreeTransactionDetailModel.getStatus());
        assertEquals(TRANSACTION_DATE, brainTreeTransactionDetailModel.getTransactionDate());
        assertEquals(SETTLEMENT_BATCH, brainTreeTransactionDetailModel.getSettlementBatch());
        assertEquals(AVS_RESPONSE, brainTreeTransactionDetailModel.getAvsResponse());
        assertEquals(CVV_RESPONSE, brainTreeTransactionDetailModel.getCvvResponse());
        assertEquals(PROCESSOR_AUTHORIZATION_CODE, brainTreeTransactionDetailModel.getProcessorAuthorizationCode());
        assertEquals(AMOUNT, brainTreeTransactionDetailModel.getAmount());
        assertEquals(REFUND, brainTreeTransactionDetailModel.getRefund());
        assertEquals(RISK_DECISION, brainTreeTransactionDetailModel.getRiskDecision());
        assertEquals(CARDHOLDER_NAME, brainTreeTransactionDetailModel.getCreditCartInfo().getCardholderName());
        assertEquals(CARD_TYPE, brainTreeTransactionDetailModel.getCreditCartInfo().getCardType());
        assertEquals(CREDIT_CARD_NUMBER, brainTreeTransactionDetailModel.getCreditCartInfo().getCreditCardNumber());
        assertEquals(EXPIRATION_DATE, brainTreeTransactionDetailModel.getCreditCartInfo().getExpirationDate());
        assertEquals(TOKEN, brainTreeTransactionDetailModel.getCreditCartInfo().getToken());
        assertEquals(UNIQUE_NUMBER_IDENTIFIER, brainTreeTransactionDetailModel.getCreditCartInfo().getUniqueNumberIdentifier());
        assertEquals(AUTHORIZATION_UNIQUE_TRANSACTION_ID, brainTreeTransactionDetailModel.getPayPalInfo().getAuthorizationUniqueTransactionID());
        assertEquals(PAYEE_EMAIL, brainTreeTransactionDetailModel.getPayPalInfo().getPayeeEmail());
        assertEquals(PAYER_EMAIL, brainTreeTransactionDetailModel.getPayPalInfo().getPayerEmail());
        assertEquals(PAYER_FIRST_NAME, brainTreeTransactionDetailModel.getPayPalInfo().getPayerFirstName());
        assertEquals(PAYMENT_ID, brainTreeTransactionDetailModel.getPayPalInfo().getPaymentID());
        assertEquals(PAY_PAL_CAPTURE_ID, brainTreeTransactionDetailModel.getPayPalInfo().getPayPalCaptureID());
        assertEquals(PAY_PAL_CUSTOM_FIELD, brainTreeTransactionDetailModel.getPayPalInfo().getPayPalCustomField());
        assertEquals(PAY_PAL_DEBUG_ID, brainTreeTransactionDetailModel.getPayPalInfo().getPayPalDebugID());
        assertEquals(PAY_PAL_REFUND_ID, brainTreeTransactionDetailModel.getPayPalInfo().getPayPalRefundID());
        assertEquals(PAY_PAL_SELLER_PROTECTION_STATUS, brainTreeTransactionDetailModel.getPayPalInfo().getPayPalSellerProtection());
        assertEquals(PAY_PAL_TOKEN, brainTreeTransactionDetailModel.getPayPalInfo().getToken());
    }

    @Test
    public void shouldPopulateBraintreeTransactionEntryToBrainTreeTransactionDetailWithSomeNullValuesTest() {
        BrainTreeTransactionDetailModel brainTreeTransactionDetailModel = new BrainTreeTransactionDetailModel();
        when(entryDetailData.getPaymentInfo()).thenReturn(null);
        when(entryDetailData.getPaymentPayPalInfo()).thenReturn(null);
        when(entryDetailData.getCustomerInfo()).thenReturn(null);

        unit.populate(entryData, brainTreeTransactionDetailModel);

        assertNull(brainTreeTransactionDetailModel.getCreditCartInfo().getToken());
        assertNull(brainTreeTransactionDetailModel.getPayPalInfo().getToken());
        assertNull(brainTreeTransactionDetailModel.getCustomer().getCustomerID());
    }

    @Test
    public void shouldPopulateBraintreeTransactionEntryToBrainTreeTransactionDetailWhenEntryDataIsNullTest() {
        BrainTreeTransactionDetailModel brainTreeTransactionDetailModel = new BrainTreeTransactionDetailModel();

        unit.populate(null, brainTreeTransactionDetailModel);

        assertNull(brainTreeTransactionDetailModel.getCreditCartInfo());
        assertNull(brainTreeTransactionDetailModel.getPayPalInfo());
        assertNull(brainTreeTransactionDetailModel.getCustomer());
    }

    @Test
    public void shouldPopulateBraintreeTransactionEntryToBrainTreeTransactionDetailWhenDetailsIsNullTest() {
        BrainTreeTransactionDetailModel brainTreeTransactionDetailModel = new BrainTreeTransactionDetailModel();
        when(entryData.getDetails()).thenReturn(null);

        unit.populate(entryData, brainTreeTransactionDetailModel);

        assertNull(brainTreeTransactionDetailModel.getCreditCartInfo());
        assertNull(brainTreeTransactionDetailModel.getPayPalInfo());
        assertNull(brainTreeTransactionDetailModel.getCustomer());
    }
}
