package com.creatubbles.api.repository;

import com.creatubbles.api.response.ResponseCallback;
import com.creatubbles.api.service.UploadService;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

import java.io.File;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.doAnswer;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.when;


/**
 * Created by Mariusz Ostapowicz on 20.03.2016.
 */
@RunWith(RobolectricTestRunner.class)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(RequestBody.class)
public class UploadRepositoryTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    private static final String ERROR_MESSAGE = "What an error!";
    private UploadRepository target;

    @Mock
    ResponseCallback<String> responseCallback;

    @Mock
    UploadService mockedUploadService;

    @Mock
    Call<String> uploadCall;

    @Mock
    RequestBody requestBody;

    File file;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        target = new UploadRepositoryImpl(mockedUploadService, RuntimeEnvironment.application);
    }

    @Test
    public void testUserByIdSuccessfulRequest() {
        Answer successfulAnswer = new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                Object[] arg = invocation.getArguments();
                Callback retrofitCallback = ((Callback) arg[arg.length - 1]);
                retrofitCallback.onResponse(null, Response.success(any(String.class)));
                return null;
            }
        };
        mockUploadServiceAnswerForUploadFile(successfulAnswer);
        target.uploadFile(any(String.class), any(MediaType.class), file, responseCallback);
        verify(responseCallback, never()).onError(any(String.class));
        verify(responseCallback).onSuccess(any(String.class));
    }

    @Test
    public void testUserByIdFailedRequest() {
        Answer failedAnswer = new Answer() {
            @Override
            public Object answer(InvocationOnMock invocation) throws Throwable {
                Object[] arg = invocation.getArguments();
                Callback retrofitCallback = ((Callback) arg[arg.length - 1]);
                retrofitCallback.onFailure(null, new Exception(ERROR_MESSAGE));
                return null;
            }
        };
        mockUploadServiceAnswerForUploadFile(failedAnswer);
        target.uploadFile(any(String.class), any(MediaType.class), file, responseCallback);
        verify(responseCallback).onError(ERROR_MESSAGE);
        verify(responseCallback, never()).onSuccess(any(String.class));
    }


    private void mockUploadServiceAnswerForUploadFile(Answer answer) {
        PowerMockito.mockStatic(RequestBody.class);
        when(RequestBody.create(any(MediaType.class), any(File.class))).thenReturn(requestBody);

        doAnswer(answer).when(uploadCall).enqueue(any(Callback.class));
        doReturn(uploadCall).when(mockedUploadService).uploadFile(anyString(), any(RequestBody.class));
    }


}

@@ -957,16 +957,55 @@
 String;%0A
+import static org.mockito.Matchers.eq;%0A
 import s
@@ -1033,24 +1033,24 @@
 kito.never;%0A
-
 import stati
@@ -1378,17 +1378,16 @@
 Ignore(%7B
- 
 %22org.moc
@@ -1427,17 +1427,16 @@
 droid.*%22
- 
 %7D)%0A@Prep
@@ -1858,16 +1858,42 @@
 tBody;%0A%0A
+    MediaType mediaType;%0A%0A
     File
@@ -2078,16 +2078,95 @@
 ation);%0A
+        file = new File(%22%22);%0A        mediaType = MediaType.parse(%22test/type%22);%0A
     %7D%0A%0A 
@@ -2748,40 +2748,21 @@
 ile(
-any(String.class), any(M
+%22%22, m
 ediaType
 .cla
@@ -2749,39 +2749,32 @@
 le(%22%22, mediaType
-.class)
 , file, response
@@ -3488,40 +3488,21 @@
 ile(
-any(String.class), any(M
+%22%22, m
 ediaType
 .cla
@@ -3497,23 +3497,16 @@
 ediaType
-.class)
 , file, 
@@ -3820,21 +3820,20 @@
 ate(
-any(M
+eq(m
 ediaType
 .cla
@@ -3828,22 +3828,16 @@
 ediaType
-.class
 ), any(F

Fix failing tests in UploadRepositoryTest