package com.braintreeocc.validators;

import com.braintree.hybris.data.ws.SrcAddressWsDTO;
import com.braintree.hybris.data.ws.SrcPaymentRequestWsDTO;
import com.braintreeocc.constants.BraintreeoccWebConstants;
import com.braintreeocc.validators.impl.BraintreeSrcPaymentRequestValidator;
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 BraintreeSrcPaymentRequestValidatorTest {

    private static final String NONCE = "nonce";
    private static final String USER_EMAIL = "userEmail";

    @Mock
    private SrcPaymentRequestWsDTO target;
    @Mock
    private SrcAddressWsDTO srcWsDTO;
    @Mock
    private Validator paymentAddressValidator;
    @Mock
    private Errors errors;

    @Spy
    @InjectMocks
    private BraintreeSrcPaymentRequestValidator unit;

    @Test
    public void shouldNotFailValidationWhenErrorsFieldIsNotNull() {
        when(target.getBillingAddress()).thenReturn(srcWsDTO);
        when(errors.getFieldValue(NONCE)).thenReturn(NONCE);
        when(errors.getFieldValue(USER_EMAIL)).thenReturn(USER_EMAIL);

        unit.validate(target, errors);

        verify(target, times(2)).getBillingAddress();
        verify(errors, never()).rejectValue(eq(NONCE), eq(BraintreeoccWebConstants.FIELD_REQUIRED_MESSAGE_ID), any(), any());
        verify(errors, never()).rejectValue(eq(USER_EMAIL), eq(BraintreeoccWebConstants.FIELD_REQUIRED_MESSAGE_ID), any(), any());
    }

    @Test
    public void shouldFailValidationWhenErrorsFieldIsNull() {
        when(target.getBillingAddress()).thenReturn(srcWsDTO);

        unit.validate(target, errors);

        verify(target, times(2)).getBillingAddress();
        verify(errors).rejectValue(eq(NONCE), eq(BraintreeoccWebConstants.FIELD_REQUIRED_MESSAGE_ID), any(), any());
        verify(errors).rejectValue(eq(USER_EMAIL), 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);
    }
}
