package com.apollographql.apollo;
import com.apollographql.android.impl.normalizer.EpisodeHeroName;
import com.apollographql.android.impl.normalizer.type.Episode;
import com.apollographql.apollo.api.Response;
import com.apollographql.apollo.exception.ApolloCanceledException;
import com.apollographql.apollo.exception.ApolloException;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nonnull;
import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
public class ApolloCallTest {
private static final long TIME_OUT_SECONDS = 3;
private ApolloClient apolloClient;
private MockWebServer mockWebServer;
@Before
public void setup() {
mockWebServer = new MockWebServer();
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
apolloClient = ApolloClient.builder()
.serverUrl(mockWebServer.url("/"))
.okHttpClient(okHttpClient)
.build();
}
@Test
public void apolloCallNotCalled_WhenCanceled() throws Exception {
final NamedCountDownLatch responseLatch = new NamedCountDownLatch("apolloCallNotCalled_WhenCanceled", 1);
EpisodeHeroName query = EpisodeHeroName.builder().episode(Episode.EMPIRE).build();
mockWebServer.enqueue(mockResponse("EpisodeHeroNameResponseWithId.json"));
ApolloCall<EpisodeHeroName.Data> apolloCall = apolloClient.query(query);
apolloCall.cancel();
apolloCall.enqueue(new ApolloCall.Callback<EpisodeHeroName.Data>() {
@Override public void onResponse(@Nonnull Response<EpisodeHeroName.Data> response) {
responseLatch.countDown();
if (responseLatch.getCount() == 0) {
fail("Received callback, although apollo call has already been canceled");
}
}
@Override public void onFailure(@Nonnull ApolloException e) {
responseLatch.countDown();
fail(e.getMessage());
}
});
//Wait for 3 seconds to check that callback is not called.
//Test is successful if timeout is reached.
responseLatch.await(TIME_OUT_SECONDS, TimeUnit.SECONDS);
}
@Test
public void apolloCanceledExceptionEnqueue() throws Exception {
final NamedCountDownLatch responseLatch = new NamedCountDownLatch("apolloCanceledExceptionEnqueue", 1);
EpisodeHeroName query = EpisodeHeroName.builder().episode(Episode.EMPIRE).build();
mockWebServer.enqueue(mockResponse("EpisodeHeroNameResponseWithId.json")
.setBodyDelay(TIME_OUT_SECONDS, TimeUnit.SECONDS));
final AtomicReference<ApolloException> errorRef = new AtomicReference<>();
ApolloCall<EpisodeHeroName.Data> apolloCall = apolloClient.query(query);
apolloCall.enqueue(new ApolloCall.Callback<EpisodeHeroName.Data>() {
@Override public void onResponse(@Nonnull Response<EpisodeHeroName.Data> response) {
responseLatch.countDown();
}
@Override public void onFailure(@Nonnull ApolloException e) {
errorRef.set(e);
responseLatch.countDown();
}
});
Thread.sleep(500);
apolloCall.cancel();
responseLatch.await(TIME_OUT_SECONDS, TimeUnit.SECONDS);
assertThat(errorRef.get()).isInstanceOf(ApolloCanceledException.class);
}
@Test
public void apolloCanceledExceptionExecute() throws Exception {
final NamedCountDownLatch responseLatch = new NamedCountDownLatch("apolloCanceledExceptionExecute", 1);
EpisodeHeroName query = EpisodeHeroName.builder().episode(Episode.EMPIRE).build();
mockWebServer.enqueue(mockResponse("EpisodeHeroNameResponseWithId.json")
.setBodyDelay(TIME_OUT_SECONDS, TimeUnit.SECONDS));
final AtomicReference<ApolloException> errorRef = new AtomicReference<>();
final ApolloCall<EpisodeHeroName.Data> apolloCall = apolloClient.query(query);
new Thread(new Runnable() {
@Override public void run() {
try {
apolloCall.execute();
} catch (ApolloException e) {
errorRef.set(e);
}
responseLatch.countDown();
}
}).start();
Thread.sleep(500);
apolloCall.cancel();
responseLatch.await(TIME_OUT_SECONDS, TimeUnit.SECONDS);
assertThat(errorRef.get()).isInstanceOf(ApolloCanceledException.class);
}
private MockResponse mockResponse(String fileName) throws IOException {
return new MockResponse().setChunkedBody(Utils.readFileToString(getClass(), "/" + fileName), 32);
}
}