package com.braintree.job;

import com.braintree.model.BrainTreePaymentInfoModel;
import com.braintree.model.ValidateExpiredCartsCronJobModel;
import com.braintree.payment.info.service.BraintreePaymentInfoService;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.core.model.BraintreeHostedFieldsConfigurationModel;
import de.hybris.platform.core.model.BraintreePluginConfigurationModel;
import de.hybris.platform.core.servicelayer.data.PaginationData;
import de.hybris.platform.core.servicelayer.data.SearchPageData;
import de.hybris.platform.cronjob.enums.CronJobResult;
import de.hybris.platform.cronjob.enums.CronJobStatus;
import de.hybris.platform.servicelayer.cronjob.PerformResult;
import de.hybris.platform.store.BaseStoreModel;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.List;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

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

    @Mock
    private BraintreePaymentInfoService braintreePaymentInfoService;
    @InjectMocks
    private ValidateExpiredCartsJobPerformable unit;

    @Mock
    private ValidateExpiredCartsCronJobModel validateExpiredCartsCronJobModel;
    @Mock
    private BraintreePluginConfigurationModel pluginConfigurationModel;
    @Mock
    private BraintreeHostedFieldsConfigurationModel hostedFieldsConfigurationModel;
    @Mock
    private BaseStoreModel store;
    @Mock
    private List<BrainTreePaymentInfoModel> paymentInfoModels;
    @Mock
    private SearchPageData<BrainTreePaymentInfoModel> searchPageData;
    @Mock
    private PaginationData paginationData;

    @Test
    public void performValidateExpiredCartsJobTest() {
        when(store.getBraintreePluginConfiguration()).thenReturn(pluginConfigurationModel);
        when(braintreePaymentInfoService.getAllSavedCreditCard(any(SearchPageData.class))).thenReturn(searchPageData);
        when(validateExpiredCartsCronJobModel.getPageSize()).thenReturn(100);
        when(validateExpiredCartsCronJobModel.getStore()).thenReturn(store);
        when(searchPageData.getResults()).thenReturn(paymentInfoModels);
        when(searchPageData.getPagination()).thenReturn(paginationData);
        when(paginationData.getCurrentPage()).thenReturn(0);
        when(paginationData.getHasNext()).thenReturn(Boolean.FALSE);

        PerformResult performResult = unit.perform(validateExpiredCartsCronJobModel);

        Assert.assertEquals(CronJobStatus.FINISHED, performResult.getStatus());
        Assert.assertEquals(CronJobResult.SUCCESS, performResult.getResult());
        verify(braintreePaymentInfoService).updateAllExpiredStatuses(paymentInfoModels, pluginConfigurationModel);
    }

    @Test
    public void performValidateExpiredCartsJobTestWhenSearchPageDataHaveNextElement() {
        when(store.getBraintreePluginConfiguration()).thenReturn(pluginConfigurationModel);
        when(braintreePaymentInfoService.getAllSavedCreditCard(any(SearchPageData.class))).thenReturn(searchPageData);
        when(validateExpiredCartsCronJobModel.getPageSize()).thenReturn(100);
        when(validateExpiredCartsCronJobModel.getStore()).thenReturn(store);
        when(searchPageData.getResults()).thenReturn(paymentInfoModels);
        when(searchPageData.getPagination()).thenReturn(paginationData);
        when(paginationData.getCurrentPage()).thenReturn(0);
        when(paginationData.getHasNext()).thenReturn(Boolean.TRUE, Boolean.FALSE);

        PerformResult performResult = unit.perform(validateExpiredCartsCronJobModel);

        Assert.assertEquals(CronJobStatus.FINISHED, performResult.getStatus());
        Assert.assertEquals(CronJobResult.SUCCESS, performResult.getResult());
        verify(braintreePaymentInfoService, times(2)).updateAllExpiredStatuses(paymentInfoModels, pluginConfigurationModel);
    }

}
