package com.avg.zaap.crashlibrary;

import android.content.Context;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.hamcrest.core.IsSame.sameInstance;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.powermock.api.support.membermodification.MemberMatcher.constructor;

/**
 * A test class for {@link CrashReportingServiceBinder}.
 * <p>
 * Created by marek.osvald on 3.5.2016.
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(CrashReportingServiceBinder.class)
public class CrashReportingServiceBinderTests {

    private ICrashServiceCommunicator.Stub mCrashReportingServiceBinder;
    @SuppressWarnings("FieldCanBeLocal")
    private Context mContext;
    private ReportData mReportData;
    private ICrashPublishingDelegate mDelegate;
    private ICrashReporter mCrashReporter;
    private ICrashServiceCallback mCrashServiceCallback;

    @Before
    public void setUp() throws Exception {
        mContext = mock(Context.class);
        mReportData = mock(ReportData.class);
        mDelegate = mock(ICrashPublishingDelegate.class);
        mCrashServiceCallback = mock(ICrashServiceCallback.class);

        PowerMockito.suppress(constructor(ICrashServiceCommunicator.Stub.class));
        mCrashReporter = mock(ICrashReporter.class);
        mCrashReportingServiceBinder = new CrashReportingServiceBinder(mContext, mCrashReporter, new ICrashReportingServiceBinderFactory() {

            @Override
            public ICrashPublishingDelegate getCrashPublishingDelegate(Context context) {
                assertThat(context, sameInstance(mContext));
                return mDelegate;
            }

        });
    }

    @Test
    public void reportAndroidCrash_errorsNotNull_reportsAndroidCrash() throws Exception {
        // act
        mCrashReportingServiceBinder.reportAndroidCrash(mReportData);

        // assert
        verify(mCrashReporter, times(1)).reportAndroidCrash(mReportData);
    }

    @Test
    public void reportAndroidCrash_errorsNull_reportsAndroidCrash() throws Exception {
        // act
        mCrashReportingServiceBinder.reportAndroidCrash(mReportData);

        // assert
        verify(mCrashReporter, times(1)).reportAndroidCrash(mReportData);
    }

    @Test
    public void publishAndroidCrash_nothing_callsDelegate() throws Exception {
        // act
        mCrashReportingServiceBinder.publishAndroidCrash(mReportData, mCrashServiceCallback);

        // assert
        verify(mDelegate, times(1)).publishCrash(mReportData, mCrashServiceCallback);
    }

}
