@Test
public void when_access_token_is_not_used_and_gfycat_returns_with_403_then_get_token_and_retry() throws Exception {

  when(data.isAccessTokenRequired())
      .thenAnswer(o -> tokenRequired);
  doAnswer(invocation -> {
    tokenRequired = invocation.getArgumentAt(0, boolean.class);
    //noinspection ReturnOfNull
    return null;
  }).when(data).setAccessTokenRequired(anyBoolean());
  HttpException forbiddenError = mock(HttpException.class);
  when(forbiddenError.code()).thenReturn(403);
  when(dankApi.gfycat(UNRESOLVED_ID)).thenReturn(Single.error(forbiddenError));
  when(data.tokenExpiryTimeMillis()).thenReturn(Single.just(0L));
  GfycatOauthResponse oAuthResponse = GfycatOauthResponse.create(3600, AUTH_TOKEN);
  when(dankApi.gfycatOAuth(anyString(), anyString())).thenReturn(Single.just(oAuthResponse));
  when(data.saveOAuthResponse(oAuthResponse)).thenReturn(Completable.complete());
  GfycatResponse response = GfycatResponse.create(GFYCAT_RESPONSE);
  when(dankApi.gfycat(AUTH_TOKEN, UNRESOLVED_ID)).thenReturn(Single.just(response));
  when(data.accessToken()).thenReturn(Single.just(AUTH_TOKEN));
  gfycatRepository.gif(UNRESOLVED_ID)
      .test()
      .assertNoErrors()
      .assertComplete()
      .assertValue(GFYCAT_RESOLVED_LINK);
  verify(data).setAccessTokenRequired(true);
  verify(dankApi).gfycatOAuth(anyString(), anyString());
  verify(data).saveOAuthResponse(oAuthResponse);
}