package com.mycompany.flightstatuslistview.homeScreen;

import android.support.annotation.NonNull;

import com.mycompany.flightstatuslistview.ArrayEmptyException;
import com.mycompany.flightstatuslistview.BuildConfig;
import com.mycompany.flightstatuslistview.FlightModel;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;

import java.util.ArrayList;

/**
 * Created by mkaratadipalayam on 12/10/16.
 */
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, manifest = "app/src/main/AndroidManifest.xml", sdk = 21)
public class HomeInteractorUnitTest {
    @Before
    public void setUp(){

    }
    @After
    public void tearDown(){

    }

    @Test
    public void fetchHomeMetaData_with_vaildInput_shouldCall_presentHomeMetaData(){
        //Given
        HomeInteractor homeInteractor = new HomeInteractor();
        HomeRequest homeRequest = new HomeRequest();
        homeRequest.isFutureTrips = true;
        HomeInteractorOutputSpy homeInteractorOutputSpy = new HomeInteractorOutputSpy();
        homeInteractor.output = homeInteractorOutputSpy;
        //When
        homeInteractor.fetchHomeMetaData(homeRequest);

        //Then
        Assert.assertTrue("When the valid input is passed to HomeInteractor Then presentHomeMetaData should be called",
                 homeInteractorOutputSpy.presentHomeMetaDataIsCalled);
    }

    @Test
    public void fetchHomeMetaData_with_vaildInput_FutureTrip_shouldCall_Worker_getFutureTrips(){
        //Given
        HomeInteractor homeInteractor = new HomeInteractor();
        HomeRequest homeRequest = new HomeRequest();
        homeRequest.isFutureTrips = true;

        //Setup TestDoubles
        HomeInteractorOutputSpy homeInteractorOutputSpy = new HomeInteractorOutputSpy();
        homeInteractor.output = homeInteractorOutputSpy;
        FlightWorkerInputSpy flightWorkerInputSpy = new FlightWorkerInputSpy();
        homeInteractor.setFlightWorkerInput(flightWorkerInputSpy);

        //When
        homeInteractor.fetchHomeMetaData(homeRequest);

        //Then
        Assert.assertTrue("When the input is passed to HomeInteractor is FutureTrip" +
                "Then getFutureFlights should be called in Worker",
                flightWorkerInputSpy.isgetFlightsMethodCalled);
    }

    @Test
    public void fetchHomeMetaData_with_vaildInput_PastTrip_shouldCall_Worker_getPastTrips(){
        //Given
        HomeInteractor homeInteractor = new HomeInteractor();
        HomeRequest homeRequest = new HomeRequest();
        homeRequest.isFutureTrips = false;

        //Setup TestDoubles
        HomeInteractorOutputSpy homeInteractorOutputSpy = new HomeInteractorOutputSpy();
        homeInteractor.output = homeInteractorOutputSpy;
        FlightWorkerInputSpy flightWorkerInputSpy = new FlightWorkerInputSpy();
        homeInteractor.setFlightWorkerInput(flightWorkerInputSpy);

        //When
        homeInteractor.fetchHomeMetaData(homeRequest);

        //Then
        Assert.assertTrue("When the input is passed to HomeInteractor is FutureTrip" +
                        "Then getFutureFlights should be called in Worker",
                flightWorkerInputSpy.isgetPastFlightsMethodCalled);
    }


    @Test(expected = ArrayEmptyException.class)
    public void fetchHomeMetaData_fetchingNull_shouldThrowArrayEmptyException(){
        //Given
        HomeInteractor homeInteractor = new HomeInteractor();
        HomeRequest homeRequest = new HomeRequest();
        homeRequest.isFutureTrips = false;

        //Setup TestDoubles
        HomeInteractorOutputSpy homeInteractorOutputSpy = new HomeInteractorOutputSpy();
        homeInteractor.output = homeInteractorOutputSpy;
        FlightWorkerInputReturnNullSpy flightWorkerInputReturnNullSpy = new FlightWorkerInputReturnNullSpy();
        homeInteractor.setFlightWorkerInput(flightWorkerInputReturnNullSpy);

        //When
        homeInteractor.fetchHomeMetaData(homeRequest);

        //Then
//      // Check for ArrayEmptyException -- See this method Annotation
    }

    private class HomeInteractorOutputSpy implements HomePresenterInput {

        boolean presentHomeMetaDataIsCalled = false;
        HomeResponse homeResponseCopy;
        @Override
        public void presentHomeMetaData(HomeResponse response) {
            presentHomeMetaDataIsCalled = true;
            homeResponseCopy = response;
        }
    }

    private class FlightWorkerInputSpy implements FlightWorkerInput {

        boolean isgetFlightsMethodCalled = false;
        boolean isgetPastFlightsMethodCalled = false;

        @Override
        public ArrayList<FlightModel> getFutureFlights() {
            isgetFlightsMethodCalled = true;
            ArrayList<FlightModel> flightsList = getFlightModels();
            return flightsList;
        }

        @Override
        public ArrayList<FlightModel> getPastFlights() {
            isgetPastFlightsMethodCalled = true;
            ArrayList<FlightModel> flightsList = getFlightModels();
            return flightsList;
        }

        @NonNull
        private ArrayList<FlightModel> getFlightModels() {
            ArrayList<FlightModel> flightsList = new ArrayList<>();
            FlightModel flight1 = new FlightModel();
            flight1.flightName = "9Z 231";
            flight1.startingTime = "2016/10/31";
            flight1.numberofSeats = "6";
            flight1.gate = "33";
            flight1.terminal = "T1";
            flightsList.add(flight1);
            return flightsList;
        }
    }

    private class FlightWorkerInputReturnNullSpy implements FlightWorkerInput {

        boolean isgetFlightsMethodCalled = false;
        boolean isgetPastFlightsMethodCalled = false;

        @Override
        public ArrayList<FlightModel> getFutureFlights() {
            isgetFlightsMethodCalled = true;
            return null;
        }

        @Override
        public ArrayList<FlightModel> getPastFlights() {
            isgetPastFlightsMethodCalled = true;
            return null;
        }
    }
}

@@ -1125,45 +1125,41 @@
 Home
-InteractorOutputSpy homeInteractorOut
+PresenterInputSpy homePresenterIn
 putS
@@ -1167,37 +1167,35 @@
 y = new Home
-InteractorOut
+PresenterIn
 putSpy();%0A  
@@ -1224,37 +1224,35 @@
 utput = home
-InteractorOut
+PresenterIn
 putSpy;%0A    
@@ -1409,16 +1409,45 @@
 eractor 
+%22 +%0A                        %22
 Then pre
@@ -1499,37 +1499,35 @@
         home
-InteractorOut
+PresenterIn
 putSpy.prese
@@ -1883,45 +1883,41 @@
 Home
-InteractorOutputSpy homeInteractorOut
+PresenterInputSpy homePresenterIn
 putS
@@ -1925,37 +1925,35 @@
 y = new Home
-InteractorOut
+PresenterIn
 putSpy();%0A  
@@ -1982,37 +1982,35 @@
 utput = home
-InteractorOut
+PresenterIn
 putSpy;%0A    
@@ -2787,45 +2787,41 @@
 Home
-InteractorOutputSpy homeInteractorOut
+PresenterInputSpy homePresenterIn
 putS
@@ -2829,37 +2829,35 @@
 y = new Home
-InteractorOut
+PresenterIn
 putSpy();%0A  
@@ -2886,37 +2886,35 @@
 utput = home
-InteractorOut
+PresenterIn
 putSpy;%0A    
@@ -3730,45 +3730,41 @@
 Home
-InteractorOutputSpy homeInteractorOut
+PresenterInputSpy homePresenterIn
 putS
@@ -3772,37 +3772,35 @@
 y = new Home
-InteractorOut
+PresenterIn
 putSpy();%0A  
@@ -3833,29 +3833,27 @@
 t = home
-InteractorOut
+PresenterIn
 putSpy;%0A
@@ -4230,21 +4230,19 @@
 Home
-InteractorOut
+PresenterIn
 putS

Refactor Spy names