package com.braintree.customersupportbackoffice.populators.transaction;

import com.braintree.command.result.BrainTreeAbstractTransactionResult;
import com.braintree.hybris.data.BrainTreeResponseResultData;
import com.braintree.hybris.data.BraintreeTransactionEntryData;
import com.braintreegateway.Customer;
import com.braintreegateway.Transaction;
import de.hybris.bootstrap.annotations.UnitTest;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;

import java.math.BigDecimal;

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

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

    private static final String ID = "id";
    private static final BigDecimal AMOUNT = BigDecimal.TEN;
    private static final String CURRENCY = "usd";
    private static final String FIRST_NAME = "firstName";
    private static final String LAST_NAME = "lastName";
    @Mock
    private Transaction transaction;
    @Mock
    private Customer customer;
    @InjectMocks
    @Spy
    private BrainTreeTransactionAdditionalPopulator unit;

    @Test
    public void shouldPopulateResponseResultData() {
        BrainTreeResponseResultData target = new BrainTreeResponseResultData();
        BrainTreeAbstractTransactionResult source = new BrainTreeAbstractTransactionResult();
        source.setTransaction(transaction);

        doReturn(StringUtils.EMPTY).when(unit).formatDate(transaction);
        doReturn(null).when(unit).convertDetails(transaction);

        when(transaction.getId()).thenReturn(ID);
        when(transaction.getAmount()).thenReturn(AMOUNT);
        when(transaction.getCurrencyIsoCode()).thenReturn(CURRENCY);
        when(transaction.getCustomer()).thenReturn(customer);
        when(customer.getFirstName()).thenReturn(FIRST_NAME);
        when(customer.getLastName()).thenReturn(LAST_NAME);
        when(transaction.getStatus()).thenReturn(Transaction.Status.VOIDED);
        when(transaction.getType()).thenReturn(Transaction.Type.SALE);

        unit.populate(source, target);

        BraintreeTransactionEntryData data = target.getTransactionEntryData();
        assertNotNull(data);
        assertEquals(ID, data.getId());
        assertEquals(String.format("%s %s", AMOUNT, CURRENCY), data.getAmount());
        assertEquals(String.format("%s %s", FIRST_NAME, LAST_NAME), data.getCustomer());
        assertEquals("VOIDED", data.getStatus());
        assertEquals("SALE", data.getType());
    }

    @Test
    public void shouldNotPopulateResponseResultData() {
        BrainTreeResponseResultData target = new BrainTreeResponseResultData();
        BrainTreeAbstractTransactionResult source = new BrainTreeAbstractTransactionResult();

        unit.populate(source, target);

        BraintreeTransactionEntryData data = target.getTransactionEntryData();
        assertNull(data);
    }

    @Test
    public void shouldPopulateResponseResultDataWithNullValues() {
        BrainTreeResponseResultData target = new BrainTreeResponseResultData();
        BrainTreeAbstractTransactionResult source = new BrainTreeAbstractTransactionResult();
        source.setTransaction(transaction);

        doReturn(StringUtils.EMPTY).when(unit).formatDate(transaction);
        doReturn(null).when(unit).convertDetails(transaction);

        when(transaction.getId()).thenReturn(ID);
        when(transaction.getAmount()).thenReturn(AMOUNT);
        when(transaction.getCurrencyIsoCode()).thenReturn(CURRENCY);
        when(transaction.getCustomer()).thenReturn(null);
        when(transaction.getStatus()).thenReturn(null);
        when(transaction.getType()).thenReturn(null);

        unit.populate(source, target);

        BraintreeTransactionEntryData data = target.getTransactionEntryData();
        assertNull(data.getCustomer());
        assertNull(data.getStatus());
        assertNull(data.getType());
    }
}