package com.braintree.populators;

import com.braintree.command.result.BrainTreeRefundTransactionResult;
import com.braintree.command.result.BrainTreeTransactionResult;
import com.braintree.hybris.data.graphql.commands.request.BrainTreeExchangeLegacyIdRequest;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeMonetaryAmount;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePaymentStatus;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeRefund;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeTransaction;
import com.braintree.method.BrainTreePaymentService;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.servicelayer.dto.converter.Converter;
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 java.math.BigDecimal;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;

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

    private static final String GRAPH_QL_ID = "GraphQLId";
    private static final String LEGACY_ID = "LegacyId";
    private static final String AMOUNT = "100";

    @InjectMocks
    private BraintreeTransactionToBraintreeTransactionResultPopulator unit;

    @Mock
    private BrainTreeTransaction brainTreeTransaction;
    @Mock
    private Converter<BrainTreeRefund, BrainTreeRefundTransactionResult> refundTransactionResultConverter;
    @Mock
    private List<BrainTreeRefund> refundList;
    @Mock
    private List<BrainTreeRefundTransactionResult> refundResultList;
    @Mock
    private BrainTreePaymentService brainTreePaymentService;
    @Mock
    private BrainTreeMonetaryAmount brainTreeMonetaryAmount;

    @Before
    public void setUp() {
        when(brainTreeTransaction.getStatus()).thenReturn(BrainTreePaymentStatus.AUTHORIZED);
        when(brainTreeTransaction.getRefunds()).thenReturn(refundList);
        when(brainTreeTransaction.getAmount()).thenReturn(brainTreeMonetaryAmount);
        when(brainTreeMonetaryAmount.getValue()).thenReturn(AMOUNT);
        when(refundTransactionResultConverter.convertAll(any())).thenReturn(refundResultList);
        when(brainTreeTransaction.getLegacyId()).thenReturn(LEGACY_ID);
        when(brainTreePaymentService.exchangeLegacyIdToGraphQLId(any(BrainTreeExchangeLegacyIdRequest.class))).thenReturn(GRAPH_QL_ID);
    }

    @Test
    public void shouldPopulateBraintreeTransactionToBraintreeTransactionResult() {
        BrainTreeTransactionResult brainTreeTransactionResult = new BrainTreeTransactionResult();

        unit.populate(brainTreeTransaction, brainTreeTransactionResult);

        assertEquals(brainTreeTransactionResult.getStatus(), BrainTreePaymentStatus.AUTHORIZED.name());
        assertEquals(brainTreeTransactionResult.getRefunds(), refundResultList);
        assertEquals(brainTreeTransactionResult.getTotalAmount(), new BigDecimal(AMOUNT));
        assertEquals(brainTreeTransactionResult.getId(), LEGACY_ID);
        assertEquals(brainTreeTransactionResult.getGraphQLId(), GRAPH_QL_ID);
    }
}
