package com.instabug.reactlibrary; import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.JavaOnlyArray; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.WritableMap; import com.instabug.library.Feature; import com.instabug.reactlibrary.utils.InstabugUtil; import com.instabug.survey.OnDismissCallback; import com.instabug.survey.OnShowCallback; import com.instabug.survey.Surveys; import com.instabug.reactlibrary.utils.MainThreadHandler; import org.json.JSONArray; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.internal.verification.VerificationModeFactory; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.powermock.api.mockito.PowerMockito.doAnswer; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) @PrepareForTest({Looper.class, android.os.Handler.class, Surveys.class, SystemClock.class, Runnable.class, RNInstabugSurveysModule.class, Arguments.class, InstabugUtil.class, MainThreadHandler.class}) public class RNInstabugSurveysModuleTest { private RNInstabugSurveysModule surveysModule = new RNInstabugSurveysModule(null); private final static ScheduledExecutorService mainThread = Executors.newSingleThreadScheduledExecutor(); @Before public void mockMainThreadHandler() throws Exception { PowerMockito.mockStatic(Looper.class); Looper mockMainThreadLooper = mock(Looper.class); when(Looper.getMainLooper()).thenReturn(mockMainThreadLooper); Handler mockMainThreadHandler = mock(Handler.class); Answer<Boolean> handlerPostAnswer = new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { invocation.getArgumentAt(0, Runnable.class).run(); return true; } }; doAnswer(handlerPostAnswer).when(mockMainThreadHandler).post(any(Runnable.class)); doAnswer(handlerPostAnswer).when(mockMainThreadHandler).postDelayed(any(Runnable.class), anyLong()); PowerMockito.whenNew(Handler.class).withArguments(mockMainThreadLooper).thenReturn(mockMainThreadHandler); } /********Surveys*********/ @Test public void givenFalse$setEnabled_whenQuery_thenShouldCallNativeApiWithDisabled() { // given PowerMockito.mockStatic(Surveys.class); // when surveysModule.setEnabled(false); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.setState(Feature.State.DISABLED); } @Test public void givenTrue$setSurveysEnabled_whenQuery_thenShouldCallNativeApiWithEnabled() { // given PowerMockito.mockStatic(Surveys.class); // when surveysModule.setEnabled(true); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.setState(Feature.State.ENABLED); } @Test public void given$showSurveysIfAvailable_whenQuery_thenShouldCallNativeApi() { // given PowerMockito.mockStatic(Surveys.class); // when surveysModule.showSurveysIfAvailable(); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.showSurveyIfAvailable(); } @Test public void givenIntArgs$setThresholdForReshowingSurveyAfterDismiss_whenQuery_thenShouldCallNativeApiWithIntArgs() { // given PowerMockito.mockStatic(Surveys.class); // when surveysModule.setThresholdForReshowingSurveyAfterDismiss(2,2); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.setThresholdForReshowingSurveyAfterDismiss(2,2); } @Test public void given$getAvailableSurveys_whenQuery_thenShouldCallNativeApiAndInvokeCallback() throws Exception { // given PowerMockito.mockStatic(Surveys.class); PowerMockito.mockStatic(SystemClock.class); PowerMockito.mockStatic(Arguments.class); Callback callback = mock(Callback.class); JSONArray json = mock(JSONArray.class); // when PowerMockito.whenNew(JSONArray.class).withAnyArguments().thenReturn(json); PowerMockito.when(Arguments.createArray()).thenReturn(new JavaOnlyArray()); surveysModule.getAvailableSurveys(callback); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.getAvailableSurveys(); verify(callback).invoke(any()); } @Test public void givenIsEnabled$setAutoShowingEnabled_whenQuery_thenShouldCallNativeApiWithIsEnabled() { // given PowerMockito.mockStatic(Surveys.class); // when surveysModule.setAutoShowingEnabled(true); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.setAutoShowingEnabled(true); } @Test public void given$setOnShowSurveyHandler_whenQuery_thenShouldSetNativeCallback() { try { // given PowerMockito.mockStatic(Surveys.class); PowerMockito.mockStatic(InstabugUtil.class); // when PowerMockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) { ((OnShowCallback) invocation.getArguments()[0]).onShow(); return null; } }).when(Surveys.class, "setOnShowCallback", Matchers.anyObject()); surveysModule.setOnShowHandler(null); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); InstabugUtil.sendEvent(any(ReactApplicationContext.class), eq(Constants.IBG_ON_SHOW_SURVEY_HANDLER), Matchers.isNull(WritableMap.class)); } catch (Exception e) { e.printStackTrace(); } } @Test public void given$setOnDismissSurveyHandler_whenQuery_thenShouldSetNativeCallback() { try { // given PowerMockito.mockStatic(Surveys.class); PowerMockito.mockStatic(InstabugUtil.class); // when PowerMockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) { ((OnDismissCallback) invocation.getArguments()[0]).onDismiss(); return null; } }).when(Surveys.class, "setOnDismissCallback", Matchers.anyObject()); surveysModule.setOnDismissHandler(null); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); InstabugUtil.sendEvent(any(ReactApplicationContext.class), eq(Constants.IBG_ON_DISMISS_SURVEY_HANDLER), Matchers.isNull(WritableMap.class)); } catch (Exception e) { e.printStackTrace(); } } @Test public void givenString$showSurvey_whenQuery_thenShouldCallNativeApiWithString() { // given PowerMockito.mockStatic(Surveys.class); // when surveysModule.showSurvey("123"); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.showSurvey("123"); } @Test public void givenBoolean$hasRespondedToSurvey_whenQuery_thenShouldCallNativeApiAndInvokeCallback() { // given PowerMockito.mockStatic(Surveys.class); // when Callback callback = mock(Callback.class); surveysModule.hasRespondedToSurvey("123", callback); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.hasRespondToSurvey("123"); verify(callback).invoke(any()); } @Test public void givenBoolean$setShouldShowWelcomeScreen_whenQuery_thenShouldCallNativeApi() { // given PowerMockito.mockStatic(Surveys.class); // when surveysModule.setShouldShowWelcomeScreen(true); // then PowerMockito.verifyStatic(VerificationModeFactory.times(1)); Surveys.setShouldShowWelcomeScreen(true); } }