package com.apollographql.apollo;
import com.apollographql.android.impl.normalizer.EpisodeHeroName;
import com.apollographql.android.impl.normalizer.HeroAndFriendsNames;
import com.apollographql.android.impl.normalizer.HeroAndFriendsNamesWithIDForParentOnly;
import com.apollographql.android.impl.normalizer.HeroAndFriendsNamesWithIDs;
import com.apollographql.android.impl.normalizer.HeroAppearsIn;
import com.apollographql.android.impl.normalizer.HeroName;
import com.apollographql.android.impl.normalizer.HeroParentTypeDependentField;
import com.apollographql.android.impl.normalizer.HeroTypeDependentAliasedField;
import com.apollographql.android.impl.normalizer.SameHeroTwice;
import com.apollographql.apollo.api.Response;
import com.apollographql.apollo.cache.CacheHeaders;
import com.apollographql.apollo.cache.normalized.CacheReference;
import com.apollographql.apollo.cache.normalized.NormalizedCache;
import com.apollographql.apollo.cache.normalized.Record;
import com.apollographql.apollo.cache.normalized.lru.EvictionPolicy;
import com.apollographql.apollo.cache.normalized.lru.LruNormalizedCacheFactory;
import com.apollographql.apollo.exception.ApolloException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import static com.apollographql.android.impl.normalizer.type.Episode.EMPIRE;
import static com.apollographql.android.impl.normalizer.type.Episode.JEDI;
import static com.google.common.truth.Truth.assertThat;
public class ResponseNormalizationTest {
private ApolloClient apolloClient;
private MockWebServer server;
private NormalizedCache normalizedCache;
private final String QUERY_ROOT_KEY = "QUERY_ROOT";
@Before public void setUp() {
server = new MockWebServer();
OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
apolloClient = ApolloClient.builder()
.serverUrl(server.url("/"))
.okHttpClient(okHttpClient)
.normalizedCache(new LruNormalizedCacheFactory(EvictionPolicy.NO_EVICTION), new IdFieldCacheKeyResolver())
.dispatcher(Utils.immediateExecutorService())
.build();
normalizedCache = apolloClient.apolloStore().normalizedCache();
}
@After public void tearDown() {
try {
server.shutdown();
} catch (IOException ignored) {
}
}
private MockResponse mockResponse(String fileName) throws IOException, ApolloException {
return new MockResponse().setChunkedBody(Utils.readFileToString(getClass(), "/" + fileName), 32);
}
@Test public void testHeroName() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroNameResponse.json");
server.enqueue(mockResponse);
ApolloCall<HeroName.Data> call = apolloClient.query(new HeroName());
Response<HeroName.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY, CacheHeaders.NONE);
CacheReference reference = (CacheReference) record.field("hero");
assertThat(reference).isEqualTo(new CacheReference("hero"));
final Record heroRecord = normalizedCache.loadRecord(reference.key(),CacheHeaders.NONE);
assertThat(heroRecord.field("name")).isEqualTo("R2-D2");
}
@Test
public void testHeroNameWithVariable() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("EpisodeHeroNameResponse.json");
server.enqueue(mockResponse);
final EpisodeHeroName query = EpisodeHeroName.builder().episode(JEDI).build();
ApolloCall<EpisodeHeroName.Data> call = apolloClient.query(query);
Response<EpisodeHeroName.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference reference = (CacheReference) record.field("hero(episode:JEDI)");
assertThat(reference).isEqualTo(new CacheReference("hero(episode:JEDI)"));
final Record heroRecord = normalizedCache.loadRecord(reference.key(),CacheHeaders.NONE);
assertThat(heroRecord.field("name")).isEqualTo("R2-D2");
}
@Test
public void testHeroAppearsInQuery() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroAppearsInResponse.json");
server.enqueue(mockResponse);
final HeroAppearsIn heroAppearsInQuery = new HeroAppearsIn();
ApolloCall<HeroAppearsIn.Data> call = apolloClient.query(heroAppearsInQuery);
Response<HeroAppearsIn.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero");
assertThat(heroReference).isEqualTo(new CacheReference("hero"));
final Record hero = normalizedCache.loadRecord(heroReference.key(),CacheHeaders.NONE);
assertThat(hero.field("appearsIn")).isEqualTo(Arrays.asList("NEWHOPE", "EMPIRE", "JEDI"));
}
@Test
public void testHeroAndFriendsNamesQueryWithoutIDs() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroAndFriendsNameResponse.json");
server.enqueue(mockResponse);
final HeroAndFriendsNames heroAndFriendsNameQuery = HeroAndFriendsNames.builder().episode(JEDI).build();
ApolloCall<HeroAndFriendsNames.Data> call = apolloClient.query(heroAndFriendsNameQuery);
Response<HeroAndFriendsNames.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero(episode:JEDI)");
assertThat(heroReference).isEqualTo(new CacheReference("hero(episode:JEDI)"));
final Record heroRecord = normalizedCache.loadRecord(heroReference.key(),CacheHeaders.NONE);
assertThat(heroRecord.field("name")).isEqualTo("R2-D2");
assertThat(heroRecord.field("friends")).isEqualTo(Arrays.asList(
new CacheReference("hero(episode:JEDI).friends.0"),
new CacheReference("hero(episode:JEDI).friends.1"),
new CacheReference("hero(episode:JEDI).friends.2")
));
final Record luke = normalizedCache.loadRecord("hero(episode:JEDI).friends.0", CacheHeaders.NONE);
assertThat(luke.field("name")).isEqualTo("Luke Skywalker");
}
@Test
public void testHeroAndFriendsNamesQueryWithIDs() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroAndFriendsNameWithIdsResponse.json");
server.enqueue(mockResponse);
final HeroAndFriendsNamesWithIDs heroAndFriendsWithIdsQuery = HeroAndFriendsNamesWithIDs.builder().episode(JEDI).build();
ApolloCall<HeroAndFriendsNamesWithIDs.Data> call = apolloClient.query(heroAndFriendsWithIdsQuery);
Response<HeroAndFriendsNamesWithIDs.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero(episode:JEDI)");
assertThat(heroReference).isEqualTo(new CacheReference("2001"));
final Record heroRecord = normalizedCache.loadRecord(heroReference.key(),CacheHeaders.NONE);
assertThat(heroRecord.field("name")).isEqualTo("R2-D2");
assertThat(heroRecord.field("friends")).isEqualTo(Arrays.asList(
new CacheReference("1000"),
new CacheReference("1002"),
new CacheReference("1003")
));
final Record luke = normalizedCache.loadRecord("1000",CacheHeaders.NONE);
assertThat(luke.field("name")).isEqualTo("Luke Skywalker");
}
@Test
public void testHeroAndFriendsNamesWithIDForParentOnly() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroAndFriendsNameWithIdsParentOnlyResponse.json");
server.enqueue(mockResponse);
final HeroAndFriendsNamesWithIDForParentOnly heroAndFriendsWithIdsQuery = HeroAndFriendsNamesWithIDForParentOnly
.builder().episode(JEDI).build();
ApolloCall<HeroAndFriendsNamesWithIDForParentOnly.Data> call = apolloClient.query(heroAndFriendsWithIdsQuery);
Response<HeroAndFriendsNamesWithIDForParentOnly.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero(episode:JEDI)");
assertThat(heroReference).isEqualTo(new CacheReference("2001"));
final Record heroRecord = normalizedCache.loadRecord(heroReference.key(),CacheHeaders.NONE);
assertThat(heroRecord.field("name")).isEqualTo("R2-D2");
assertThat(heroRecord.field("friends")).isEqualTo(Arrays.asList(
new CacheReference("2001.friends.0"),
new CacheReference("2001.friends.1"),
new CacheReference("2001.friends.2")
));
final Record luke = normalizedCache.loadRecord("2001.friends.0",CacheHeaders.NONE);
assertThat(luke.field("name")).isEqualTo("Luke Skywalker");
}
@Test
public void testSameHeroTwiceQuery() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("SameHeroTwiceResponse.json");
server.enqueue(mockResponse);
final SameHeroTwice sameHeroTwiceQuery = new SameHeroTwice();
ApolloCall<SameHeroTwice.Data> call = apolloClient.query(sameHeroTwiceQuery);
Response<SameHeroTwice.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache
.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero");
final Record hero = normalizedCache.loadRecord(heroReference.key(), CacheHeaders.NONE);
assertThat(hero.field("name")).isEqualTo("R2-D2");
assertThat(hero.field("appearsIn")).isEqualTo(Arrays.asList("NEWHOPE", "EMPIRE", "JEDI"));
}
@Test
public void testHeroTypeDependentAliasedFieldQueryDroid() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroTypeDependentAliasedFieldResponse.json");
server.enqueue(mockResponse);
final HeroTypeDependentAliasedField aliasedQuery = HeroTypeDependentAliasedField.builder().episode(JEDI).build();
ApolloCall<HeroTypeDependentAliasedField.Data> call = apolloClient.query(aliasedQuery);
Response<HeroTypeDependentAliasedField.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero(episode:JEDI)");
final Record hero = normalizedCache.loadRecord(heroReference.key(),CacheHeaders.NONE);
assertThat(hero.field("primaryFunction")).isEqualTo("Astromech");
assertThat(hero.field("__typename")).isEqualTo("Droid");
}
@Test
public void testHeroTypeDependentAliasedFieldQueryHuman() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroTypeDependentAliasedFieldResponseHuman.json");
server.enqueue(mockResponse);
final HeroTypeDependentAliasedField aliasedQuery = HeroTypeDependentAliasedField.builder().episode(EMPIRE).build();
ApolloCall<HeroTypeDependentAliasedField.Data> call = apolloClient.query(aliasedQuery);
Response<HeroTypeDependentAliasedField.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero(episode:EMPIRE)");
final Record hero = normalizedCache.loadRecord(heroReference.key(),CacheHeaders.NONE);
assertThat(hero.field("homePlanet")).isEqualTo("Tatooine");
assertThat(hero.field("__typename")).isEqualTo("Human");
}
@Test
public void testHeroParentTypeDependentAliasedFieldQueryHuman() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroTypeDependentAliasedFieldResponseHuman.json");
server.enqueue(mockResponse);
final HeroTypeDependentAliasedField aliasedQuery = HeroTypeDependentAliasedField.builder().episode(EMPIRE).build();
ApolloCall<HeroTypeDependentAliasedField.Data> call = apolloClient.query(aliasedQuery);
Response<HeroTypeDependentAliasedField.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record record = normalizedCache.loadRecord(QUERY_ROOT_KEY,CacheHeaders.NONE);
CacheReference heroReference = (CacheReference) record.field("hero(episode:EMPIRE)");
final Record hero = normalizedCache.loadRecord(heroReference.key(),CacheHeaders.NONE);
assertThat(hero.field("homePlanet")).isEqualTo("Tatooine");
assertThat(hero.field("__typename")).isEqualTo("Human");
}
@Test
public void testHeroParentTypeDependentFieldDroid() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroParentTypeDependentFieldDroidResponse.json");
server.enqueue(mockResponse);
final HeroParentTypeDependentField aliasedQuery = HeroParentTypeDependentField.builder().episode(JEDI).build();
ApolloCall<HeroParentTypeDependentField.Data> call = apolloClient.query(aliasedQuery);
Response<HeroParentTypeDependentField.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record lukeRecord = normalizedCache
.loadRecord("hero(episode:JEDI).friends.0", CacheHeaders.NONE);
assertThat(lukeRecord.field("name")).isEqualTo("Luke Skywalker");
assertThat(lukeRecord.field("height(unit:METER)")).isEqualTo(BigDecimal.valueOf(1.72));
final List<Object> friends = (List<Object>) normalizedCache
.loadRecord("hero(episode:JEDI)",CacheHeaders.NONE).field("friends");
assertThat(friends.get(0)).isEqualTo(new CacheReference("hero(episode:JEDI).friends.0"));
assertThat(friends.get(1)).isEqualTo(new CacheReference("hero(episode:JEDI).friends.1"));
assertThat(friends.get(2)).isEqualTo(new CacheReference("hero(episode:JEDI).friends.2"));
}
@Test
public void testHeroParentTypeDependentFieldHuman() throws IOException, ApolloException {
MockResponse mockResponse = mockResponse("HeroParentTypeDependentFieldHumanResponse.json");
server.enqueue(mockResponse);
final HeroParentTypeDependentField aliasedQuery = HeroParentTypeDependentField.builder().episode(EMPIRE).build();
ApolloCall<HeroParentTypeDependentField.Data> call = apolloClient.query(aliasedQuery);
Response<HeroParentTypeDependentField.Data> body = call.execute();
assertThat(body.hasErrors()).isFalse();
Record lukeRecord = normalizedCache
.loadRecord("hero(episode:EMPIRE).friends.0",CacheHeaders.NONE);
assertThat(lukeRecord.field("name")).isEqualTo("Han Solo");
assertThat(lukeRecord.field("height(unit:FOOT)")).isEqualTo(BigDecimal.valueOf(5.905512));
}
}