package com.braintree.customersupportbackoffice.actions.order.refreshpaymentstatus;

import com.braintree.enums.BraintreePaymentTransactionStatus;
import com.braintree.facade.backoffice.BraintreeBackofficeRefreshPaymentStatusFacade;
import com.hybris.cockpitng.actions.ActionContext;
import com.hybris.cockpitng.actions.ActionResult;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.payment.model.PaymentTransactionModel;
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.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@UnitTest
@RunWith(MockitoJUnitRunner.class)
public class BraintreeRefreshPaymentStatusOrderActionTest {
    @Mock
    private BraintreeBackofficeRefreshPaymentStatusFacade braintreeBackofficeRefreshPaymentStatusFacade;

    @Spy
    @InjectMocks
    private BraintreeRefreshPaymentStatusOrderAction unit;

    @Mock
    private ActionContext<OrderModel> actionContext;
    @Mock
    private OrderModel order;
    @Mock
    private PaymentTransactionModel paymentTransaction;

    @Test
    public void shouldReturnTrueIfRefreshStatusesPossible() {
        when(paymentTransaction.getBraintreePaymentTransactionStatus()).thenReturn(BraintreePaymentTransactionStatus.AUTHORIZED);
        when(order.getPaymentTransactions()).thenReturn(List.of(paymentTransaction));
        when(actionContext.getData()).thenReturn(order);

        boolean result = unit.canPerform(actionContext);

        assertTrue(result);
    }

    @Test
    public void shouldReturnFalseIfRefreshStatusesNotPossible() {
        when(paymentTransaction.getBraintreePaymentTransactionStatus()).thenReturn(BraintreePaymentTransactionStatus.SETTLED);
        when(order.getPaymentTransactions()).thenReturn(List.of(paymentTransaction));
        when(actionContext.getData()).thenReturn(order);

        boolean result = unit.canPerform(actionContext);

        assertFalse(result);
    }

    @Test
    public void shouldReturnFalseIfActionContextDoesNotHaveOrder() {
        boolean result = unit.canPerform(actionContext);

        assertFalse(result);
    }

    @Test
    public void shouldSuccessfullyPerform() {
        doNothing().when(unit).showMessage(actionContext);
        when(actionContext.getData()).thenReturn(order);
        when(order.getPaymentTransactions()).thenReturn(List.of(paymentTransaction));

        ActionResult<OrderModel> result = unit.perform(actionContext);

        assertEquals(ActionResult.SUCCESS, result.getResultCode());
        verify(braintreeBackofficeRefreshPaymentStatusFacade).updateBraintreePaymentTransactionStatuses(List.of(paymentTransaction));
    }
}
