package com.braintree.service;

import com.braintree.configuration.service.BrainTreeConfigService;
import com.braintree.enums.BrainTreePaymentMethod;
import com.braintree.hybris.data.graphql.commands.request.BrainTreeTransactionDescriptorInput;
import com.braintree.service.impl.DefaultBrainTreeDescriptorService;
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.runners.MockitoJUnitRunner;

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

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

    private static final String PAYPAL_PRODUCT_NAME_PREFIX = "PAYPAL ";
    private static final String VENMO_PRODUCT_NAME_PREFIX = "VENMO  ";
    private static final String ASTERISK = "*";
    private static final String BUSINESS_NAME = "business";
    private static final String PRODUCT_NAME = "product";
    private static final String URL = "url.com";
    private static final String PHONE = "0000000000";

    @Mock
    BrainTreeConfigService brainTreeConfigService;
    @InjectMocks
    DefaultBrainTreeDescriptorService descriptorService;

    @Test
    public void shouldReturnTrueWhenDescriptorAvailableToUse() {
        when((brainTreeConfigService.getDescriptorPhoneNumber())).thenReturn(PHONE);
        when(brainTreeConfigService.getDescriptorBusinessName()).thenReturn(BUSINESS_NAME);
        when(brainTreeConfigService.getDescriptorUrl()).thenReturn(URL);

        assertTrue(descriptorService.isDescriptorAvailable(BrainTreePaymentMethod.PAYPALACCOUNT.getCode()));
    }

    @Test
    public void shouldReturnFalseWhenDescriptorNotAvailableBecausePropertyIsNull() {
        when(brainTreeConfigService.getDescriptorBusinessName()).thenReturn(BUSINESS_NAME);
        when((brainTreeConfigService.getDescriptorPhoneNumber())).thenReturn(PHONE);
        when(brainTreeConfigService.getDescriptorUrl()).thenReturn(null);

        assertFalse(descriptorService.isDescriptorAvailable(BrainTreePaymentMethod.PAYPALACCOUNT.getCode()));
    }

    @Test
    public void shouldReturnFalseWhenDescriptorNotAvailableBecausePaymentIsACH() {
        assertFalse(descriptorService.isDescriptorAvailable(BrainTreePaymentMethod.USBANKACCOUNT.getCode()));
    }

    @Test
    public void shouldGetTransactionDescriptorWhenPaidWithPayPal() {
        when((brainTreeConfigService.getDescriptorPhoneNumber())).thenReturn(PHONE);
        when(brainTreeConfigService.getDescriptorProductName()).thenReturn(PRODUCT_NAME);
        when(brainTreeConfigService.getDescriptorUrl()).thenReturn(URL);

        BrainTreeTransactionDescriptorInput input = descriptorService.getTransactionDescriptor(BrainTreePaymentMethod.PAYPALACCOUNT.getCode());

        assertNotNull(input);
        assertTrue(input.getName().startsWith(PAYPAL_PRODUCT_NAME_PREFIX + ASTERISK));
        assertTrue(input.getName().endsWith(PRODUCT_NAME));
        assertEquals(input.getUrl(), URL);
        assertEquals(input.getPhone(), PHONE);
    }

    @Test
    public void shouldGetTransactionDescriptorWhenPaidWithVenmo() {
        when((brainTreeConfigService.getDescriptorPhoneNumber())).thenReturn(PHONE);
        when(brainTreeConfigService.getDescriptorProductName()).thenReturn(PRODUCT_NAME);
        when(brainTreeConfigService.getDescriptorUrl()).thenReturn(URL);

        BrainTreeTransactionDescriptorInput input = descriptorService.getTransactionDescriptor(BrainTreePaymentMethod.VENMOACCOUNT.getCode());

        assertNotNull(input);
        assertTrue(input.getName().startsWith(VENMO_PRODUCT_NAME_PREFIX + ASTERISK));
        assertTrue(input.getName().endsWith(PRODUCT_NAME));
        assertEquals(input.getUrl(), URL);
        assertEquals(input.getPhone(), PHONE);
    }

    @Test
    public void shouldGetTransactionDescriptorWhenPaidWithCard() {
        when((brainTreeConfigService.getDescriptorPhoneNumber())).thenReturn(PHONE);
        when(brainTreeConfigService.getDescriptorProductName()).thenReturn(PRODUCT_NAME);
        when(brainTreeConfigService.getDescriptorUrl()).thenReturn(URL);
        when(brainTreeConfigService.getDescriptorBusinessName()).thenReturn(BUSINESS_NAME);

        BrainTreeTransactionDescriptorInput input = descriptorService.getTransactionDescriptor(BrainTreePaymentMethod.CREDITCARD.getCode());

        assertNotNull(input);
        assertTrue(input.getName().startsWith(BUSINESS_NAME + ASTERISK));
        assertTrue(input.getName().endsWith(PRODUCT_NAME));
        assertEquals(input.getUrl(), URL);
        assertEquals(input.getPhone(), PHONE);
    }
}
