package com.braintreeocc.validators;

import com.braintree.hybris.data.ws.BraintreeCreditCardPaymentDetailsWsDTO;
import com.braintree.hybris.data.ws.BraintreeTokenizedCreditCardWsDTO;
import com.braintreeocc.constants.BraintreeoccWebConstants;
import com.braintreeocc.validators.impl.BraintreeCreditCardPaymentResponseValidator;
import de.hybris.bootstrap.annotations.UnitTest;
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 org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.never;

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

    private static final String ACCOUNT_HOLDER_NAME = "accountHolderName";

    @Mock
    private BraintreeCreditCardPaymentDetailsWsDTO target;
    @Mock
    private Validator creditCardDataValidator;
    @Mock
    private Validator paymentAddressValidator;
    @Mock
    private BraintreeTokenizedCreditCardWsDTO tokenizedCreditCardWsDTO;
    @Mock
    private Errors errors;

    @Spy
    @InjectMocks
    private BraintreeCreditCardPaymentResponseValidator unit;

    @Test
    public void shouldNotFailValidationWhenErrorsFieldIsNotNull() {
        when(target.getTokenizedCardData()).thenReturn(tokenizedCreditCardWsDTO);
        when(errors.getFieldValue(ACCOUNT_HOLDER_NAME)).thenReturn(ACCOUNT_HOLDER_NAME);

        unit.validate(target, errors);

        verify(target, times(2)).getTokenizedCardData();
        verify(errors, never()).rejectValue(eq(ACCOUNT_HOLDER_NAME), eq(BraintreeoccWebConstants.FIELD_REQUIRED_MESSAGE_ID), any(), any());
    }

    @Test
    public void shouldFailValidationWhenErrorsFieldIsNull() {
        when(target.getTokenizedCardData()).thenReturn(tokenizedCreditCardWsDTO);

        unit.validate(target, errors);

        verify(target, times(2)).getTokenizedCardData();
        verify(errors).rejectValue(eq(ACCOUNT_HOLDER_NAME), eq(BraintreeoccWebConstants.FIELD_REQUIRED_MESSAGE_ID), any(), any());
    }

    @Test
    public void shouldReturnTrueIfPassedSupportedClass() {
        boolean isSupported = unit.supports(target.getClass());

        assertTrue(isSupported);
    }

    @Test
    public void shouldReturnFalseIfPassedUnsupportedClass() {
        boolean isSupported = unit.supports(Object.class);

        assertFalse(isSupported);
    }
}
