package com.braintree.graphql.commands.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.payment.AdapterException;
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.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static com.braintree.constants.BraintreeConstants.RESULT_DATA;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.doThrow;

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

    private static final String MUTATION_NAME = "ping";
    private static final String PONG = "pong";

    @Mock
    private Map<String, Object> data;

    @Mock
    private ObjectMapper objectMapper;

    @Spy
    @InjectMocks
    private DefaultBrainTreeGraphQLPingCommand command;

    @Test
    public void shouldMakeGraphQlCall() throws IOException {
        final Map<String, Object> result = mock(HashMap.class);

        doReturn(result).when(command).makeGraphQlCall(MUTATION_NAME);
        when(result.get(RESULT_DATA)).thenReturn(data);
        doReturn(PONG).when(command).translateResponse(data);

        assertEquals(PONG, command.perform(null));

        verify(command).makeGraphQlCall(MUTATION_NAME);
        verify(result).get(RESULT_DATA);
        verify(command).translateResponse(data);
    }

    @Test(expected = AdapterException.class)
    public void shouldThrowException() throws IOException {
        doThrow(new IOException()).when(command).makeGraphQlCall(MUTATION_NAME);
        command.perform(null);
    }

    @Test
    public void shouldTranslateResponse() {
        final Object object = mock(Object.class);

        when(data.get(MUTATION_NAME)).thenReturn(object);
        when(objectMapper.convertValue(object, String.class)).thenReturn(PONG);

        assertEquals(PONG, command.translateResponse(data));

        verify(data).get(MUTATION_NAME);
        verify(objectMapper).convertValue(object, String.class);
    }

}
