Gandalf { @SuppressWarnings("PMD.AvoidCatchingGenericException") public void shallIPass(Context context, final GandalfCallback gandalfCallback) { LoggerUtil.logD("Fetching bootstrap"); new BootstrapApi(context, okHttpClient, bootstrapUrl, customDeserializer, callbackExecutor) .fetchBootstrap(new BootstrapCallback() { @Override public void onSuccess(Bootstrap bootstrap) { LoggerUtil.logD("Fetched bootstrap: " + bootstrap); try { if (gateKeeper.updateIsRequired(bootstrap)) { LoggerUtil.logD("Update is required"); gandalfCallback.onRequiredUpdate(bootstrap.getRequiredUpdate()); } else if (gateKeeper.showAlert(bootstrap)) { LoggerUtil.logD("Alert"); gandalfCallback.onAlert(bootstrap.getAlert()); } else if (gateKeeper.updateIsOptional(bootstrap)) { LoggerUtil.logD("Update is optional"); gandalfCallback.onOptionalUpdate(bootstrap.getOptionalUpdate()); } else { LoggerUtil.logD("No action is required"); gandalfCallback.onNoActionRequired(); } } catch (Exception e) { LoggerUtil.logE(e.getMessage()); gandalfCallback.onNoActionRequired(); } } @Override public void onError(Exception e) { LoggerUtil.logE("Error fetching bootstrap: " + e.getMessage()); gandalfCallback.onNoActionRequired(); } }); } private  Gandalf(
            OkHttpClient okHttpClient,
            String bootstrapUrl,
            HistoryChecker historyChecker,
            GateKeeper gateKeeper,
            OnUpdateSelectedListener onUpdateSelectedListener,
            JsonDeserializer<Bootstrap> customDeserializer,
            DialogStringsHolder dialogStringsHolder,
            Executor callbackExecutor
    ); static Gandalf get(); OnUpdateSelectedListener getOnUpdateSelectedListener(); DialogStringsHolder getDialogStringsHolder(); boolean save(@NonNull final OptionalUpdate optionalUpdate); boolean save(@NonNull final Alert alert); @SuppressWarnings("PMD.AvoidCatchingGenericException") void shallIPass(Context context, final GandalfCallback gandalfCallback);  }
@Test public void invalidVersionCodeSafelyCallsNoActionRequired() throws IOException, PackageManager.NameNotFoundException, InterruptedException { enqueueMockResponse("invalidVersion.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onNoActionRequired(); }
@Test public void updateRequiredButHigherVersion() throws IOException, PackageManager.NameNotFoundException, InterruptedException { enqueueMockResponse("updateRequired.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 8).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onNoActionRequired(); }
@Test public void updateRequiredAndLowerVersion() throws IOException, PackageManager.NameNotFoundException, InterruptedException { enqueueMockResponse("updateRequired.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onRequiredUpdate(any(RequiredUpdate.class)); }
@Test public void updateOptionalButHigherVersion() throws IOException, PackageManager.NameNotFoundException, InterruptedException { when(mockSharedPreferences.getString(anyString(), anyString())).thenReturn(""); enqueueMockResponse("updateOptional.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 8).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onNoActionRequired(); }
@Test public void updateOptionalAndLowerVersion() throws IOException, PackageManager.NameNotFoundException, InterruptedException { when(mockSharedPreferences.getString(anyString(), anyString())).thenReturn(""); enqueueMockResponse("updateOptional.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onOptionalUpdate(any(OptionalUpdate.class)); }
@Test public void updateOptionalAndLowerVersionAlreadySeen() throws IOException, PackageManager.NameNotFoundException, InterruptedException { when(mockSharedPreferences.getString(anyString(), anyString())).thenReturn("7"); enqueueMockResponse("updateOptional.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onNoActionRequired(); }
@Test public void blockingAlert() throws IOException, PackageManager.NameNotFoundException, InterruptedException { when(mockSharedPreferences.getString(anyString(), anyString())).thenReturn(""); enqueueMockResponse("blockingAlert.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onAlert(argThat(new ArgumentMatcher<Alert>() { @Override public boolean matches(Alert alert) { return alert.isBlocking() && ALERT_MESSAGE.equals(alert.getMessage()); } })); }
@Test public void blockingAlertAlreadySeen() throws IOException, PackageManager.NameNotFoundException, InterruptedException { when(mockSharedPreferences.getString(anyString(), anyString())).thenReturn(ALERT_MESSAGE); enqueueMockResponse("blockingAlert.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onAlert(argThat(new ArgumentMatcher<Alert>() { @Override public boolean matches(Alert alert) { return alert.isBlocking() && ALERT_MESSAGE.equals(alert.getMessage()); } })); }
@Test public void nonBlockingAlert() throws IOException, PackageManager.NameNotFoundException, InterruptedException { when(mockSharedPreferences.getString(anyString(), anyString())).thenReturn(""); enqueueMockResponse("nonBlockingAlert.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onAlert(argThat(new ArgumentMatcher<Alert>() { @Override public boolean matches(Alert alert) { return !alert.isBlocking() && ALERT_MESSAGE.equals(alert.getMessage()); } })); }
@Test public void nonBlockingAlertAlreadySeen() throws IOException, PackageManager.NameNotFoundException, InterruptedException { when(mockSharedPreferences.getString(anyString(), anyString())).thenReturn(ALERT_MESSAGE); enqueueMockResponse("nonBlockingAlert.json"); final CountDownLatch countDownLatch = new CountDownLatch(1); GandalfCallback mockCallback = getGandalfCallback(countDownLatch); getGandalfInstance(VERSION_NAME, 6).shallIPass(mockContext, mockCallback); boolean status = countDownLatch.await(5, TimeUnit.SECONDS); assertTrue(LATCH_TIMEOUT_MESSAGE, status); verify(mockCallback).onNoActionRequired(); }