use of com.amplifyframework.api.graphql.GraphQLResponse in project amplify-android by aws-amplify.
the class GsonGraphQLResponseFactoryTest method responseRendersAsPaginatedResult.
/**
* Validates that the converter is able to parse a partial GraphQL
* response into a result. In this case, the result contains some
* data, but also a list of errors.
* @throws AmplifyException From API configuration
*/
@Test
public void responseRendersAsPaginatedResult() throws AmplifyException {
// Expect
final List<Todo> expectedTodos = Arrays.asList(Todo.builder().id("fa1c21cc-0458-4bca-bcb1-101579fb85c7").name(null).description("Test").build(), Todo.builder().id("68bad242-dec5-415b-acb3-daee3b069ce5").name(null).description("Test").build(), Todo.builder().id("f64e2e9a-42ad-4455-b8ee-d1cfae7e9f01").name(null).description("Test").build());
String nextToken = "eyJ2ZXJzaW9uIjoyLCJ0b2tlbiI6IkFRSUNBSGg5OUIvN3BjWU41eE96NDZJMW5GeGM4";
Type responseType = TypeMaker.getParameterizedType(PaginatedResult.class, Todo.class);
AppSyncGraphQLRequest<PaginatedResult<Todo>> expectedRequest = buildDummyRequest(responseType);
expectedRequest = expectedRequest.newBuilder().variable("nextToken", "String", nextToken).build();
final PaginatedResult<Todo> expectedPaginatedResult = new PaginatedResult<>(expectedTodos, expectedRequest);
final List<GraphQLResponse.Error> expectedErrors = new ArrayList<>();
for (int i = 0; i < 3; i++) {
String message = "failed";
List<GraphQLLocation> locations = Collections.singletonList(new GraphQLLocation(5, 7));
List<GraphQLPathSegment> path = Arrays.asList(new GraphQLPathSegment("listTodos"), new GraphQLPathSegment("items"), new GraphQLPathSegment(i), new GraphQLPathSegment("name"));
Map<String, Object> extensions = new HashMap<>();
extensions.put("errorType", null);
extensions.put("errorInfo", null);
extensions.put("data", null);
expectedErrors.add(new GraphQLResponse.Error(message, locations, path, extensions));
}
final GraphQLResponse<PaginatedResult<Todo>> expectedResponse = new GraphQLResponse<>(expectedPaginatedResult, expectedErrors);
// Act
final String partialResponseJson = Resources.readAsString("partial-gql-response.json");
final GraphQLRequest<PaginatedResult<Todo>> request = buildDummyRequest(responseType);
final GraphQLResponse<PaginatedResult<Todo>> response = responseFactory.buildResponse(request, partialResponseJson);
// Assert
assertEquals(expectedResponse, response);
}
use of com.amplifyframework.api.graphql.GraphQLResponse in project amplify-android by aws-amplify.
the class GsonGraphQLResponseFactoryTest method errorWithNullMessageCanBeParsed.
/**
* If an {@link GraphQLResponse} contains a non-null {@link GraphQLResponse.Error},
* and if that error object "message" as a null, the response factory
* should be resilient to this, and continue to render a response, anyway, without
* throwing an exception over the issue but adding a default message notifying that the
* message was null or missing.
* @throws ApiException On failure to build a response, perhaps because the null
* valued items inside of the {@link GraphQLResponse.Error}
* could not be parsed
*/
@Test
public void errorWithNullMessageCanBeParsed() throws ApiException {
// Arrange some JSON string from a "server"
final String responseJson = Resources.readAsString("error-null-message.json");
// Act! Parse it into a model.
Type responseType = TypeMaker.getParameterizedType(PaginatedResult.class, Todo.class);
GraphQLRequest<PaginatedResult<Todo>> request = buildDummyRequest(responseType);
final GraphQLResponse<PaginatedResult<Todo>> response = responseFactory.buildResponse(request, responseJson);
// Build the expected response.
Map<String, Object> extensions = new HashMap<>();
extensions.put("errorType", null);
extensions.put("errorInfo", null);
extensions.put("data", null);
final String defaultMessage = "Message was null or missing while deserializing error";
GraphQLResponse.Error expectedError = new GraphQLResponse.Error(defaultMessage, null, null, extensions);
GraphQLResponse<PaginatedResult<Todo>> expectedResponse = new GraphQLResponse<>(null, Collections.singletonList(expectedError));
// Assert that the response is expected
assertEquals(expectedResponse, response);
}
use of com.amplifyframework.api.graphql.GraphQLResponse in project amplify-android by aws-amplify.
the class SubscriptionProcessorTest method arrangeDataEmittingSubscription.
@SuppressWarnings("SameParameterValue")
private static <T extends Model> void arrangeDataEmittingSubscription(AppSync appSync, ModelSchema modelSchema, SubscriptionType subscriptionType, GraphQLResponse<ModelWithMetadata<T>> response) throws DataStoreException {
Answer<Cancelable> answer = invocation -> {
final int startConsumerIndex = 1;
Consumer<String> onStart = invocation.getArgument(startConsumerIndex);
onStart.accept(RandomString.string());
final int dataConsumerIndex = 2;
Consumer<GraphQLResponse<ModelWithMetadata<T>>> onData = invocation.getArgument(dataConsumerIndex);
onData.accept(response);
return new NoOpCancelable();
};
arrangeSubscription(appSync, answer, modelSchema, subscriptionType);
}
use of com.amplifyframework.api.graphql.GraphQLResponse in project amplify-android by aws-amplify.
the class AWSDataStorePluginTest method clearStopsSyncAndDeletesDatabase.
/**
* Verify that when the clear method is called, the following happens
* - All remote synchronization processes are stopped
* - The database is deleted.
* - On the next interaction with the DataStore, the synchronization processes are restarted.
* @throws JSONException on failure to arrange plugin config
* @throws AmplifyException on failure to arrange API plugin via Amplify facade
*/
@Test
public void clearStopsSyncAndDeletesDatabase() throws AmplifyException, JSONException {
ApiCategory mockApiCategory = mockApiCategoryWithGraphQlApi();
ApiPlugin<?> mockApiPlugin = mockApiCategory.getPlugin(MOCK_API_PLUGIN_NAME);
JSONObject dataStorePluginJson = new JSONObject().put("syncIntervalInMinutes", 60);
AWSDataStorePlugin awsDataStorePlugin = AWSDataStorePlugin.builder().modelProvider(modelProvider).apiCategory(mockApiCategory).build();
SynchronousDataStore synchronousDataStore = SynchronousDataStore.delegatingTo(awsDataStorePlugin);
awsDataStorePlugin.configure(dataStorePluginJson, context);
awsDataStorePlugin.initialize(context);
// Trick the DataStore since it's not getting initialized as part of the Amplify.initialize call chain
Amplify.Hub.publish(HubChannel.DATASTORE, HubEvent.create(InitializationStatus.SUCCEEDED));
// Setup objects
Person person1 = createPerson("Test", "Dummy I");
Person person2 = createPerson("Test", "Dummy II");
// Mock responses for person 1
doAnswer(invocation -> {
int indexOfResponseConsumer = 1;
Consumer<GraphQLResponse<ModelWithMetadata<Person>>> onResponse = invocation.getArgument(indexOfResponseConsumer);
ModelMetadata modelMetadata = new ModelMetadata(person1.getId(), false, 1, Temporal.Timestamp.now());
ModelWithMetadata<Person> modelWithMetadata = new ModelWithMetadata<>(person1, modelMetadata);
onResponse.accept(new GraphQLResponse<>(modelWithMetadata, Collections.emptyList()));
return mock(GraphQLOperation.class);
}).when(mockApiPlugin).mutate(any(), any(), any());
HubAccumulator apiInteractionObserver = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.OUTBOX_MUTATION_PROCESSED, 1).start();
// Save person 1
synchronousDataStore.save(person1);
Person result1 = synchronousDataStore.get(Person.class, person1.getId());
assertEquals(person1, result1);
apiInteractionObserver.await();
verify(mockApiCategory).mutate(argThat(getMatcherFor(person1)), any(), any());
// Mock responses for person 2
doAnswer(invocation -> {
int indexOfResponseConsumer = 1;
Consumer<GraphQLResponse<ModelWithMetadata<Person>>> onResponse = invocation.getArgument(indexOfResponseConsumer);
ModelMetadata modelMetadata = new ModelMetadata(person2.getId(), false, 1, Temporal.Timestamp.now());
ModelWithMetadata<Person> modelWithMetadata = new ModelWithMetadata<>(person2, modelMetadata);
onResponse.accept(new GraphQLResponse<>(modelWithMetadata, Collections.emptyList()));
return mock(GraphQLOperation.class);
}).when(mockApiPlugin).mutate(any(), any(), any());
// Do the thing!
synchronousDataStore.clear();
assertRemoteSubscriptionsCancelled();
apiInteractionObserver = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.OUTBOX_MUTATION_PROCESSED, 1).start();
HubAccumulator orchestratorInitObserver = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.READY, 1).start();
// Interact with the DataStore after the clear
synchronousDataStore.save(person2);
// Verify person 2 was published to the cloud
apiInteractionObserver.await();
// Verify the orchestrator started back up and subscriptions are active.
orchestratorInitObserver.await();
assertRemoteSubscriptionsStarted();
Person result2 = synchronousDataStore.get(Person.class, person2.getId());
assertEquals(person2, result2);
verify(mockApiCategory, atLeastOnce()).mutate(argThat(getMatcherFor(person2)), any(), any());
}
use of com.amplifyframework.api.graphql.GraphQLResponse in project amplify-android by aws-amplify.
the class AWSDataStorePluginTest method stopStopsSyncUntilNextInteraction.
/**
* Verify that when the stop method is called, the following happens
* - All remote synchronization processes are stopped
* - On the next interaction with the DataStore, the synchronization processes are restarted.
* @throws JSONException on failure to arrange plugin config
* @throws AmplifyException on failure to arrange API plugin via Amplify facade
*/
@Test
public void stopStopsSyncUntilNextInteraction() throws AmplifyException, JSONException {
ApiCategory mockApiCategory = mockApiCategoryWithGraphQlApi();
ApiPlugin<?> mockApiPlugin = mockApiCategory.getPlugin(MOCK_API_PLUGIN_NAME);
JSONObject dataStorePluginJson = new JSONObject().put("syncIntervalInMinutes", 60);
AWSDataStorePlugin awsDataStorePlugin = AWSDataStorePlugin.builder().modelProvider(modelProvider).apiCategory(mockApiCategory).build();
SynchronousDataStore synchronousDataStore = SynchronousDataStore.delegatingTo(awsDataStorePlugin);
awsDataStorePlugin.configure(dataStorePluginJson, context);
awsDataStorePlugin.initialize(context);
// Trick the DataStore since it's not getting initialized as part of the Amplify.initialize call chain
Amplify.Hub.publish(HubChannel.DATASTORE, HubEvent.create(InitializationStatus.SUCCEEDED));
// Setup objects
Person person1 = createPerson("Test", "Dummy I");
Person person2 = createPerson("Test", "Dummy II");
// Mock responses for person 1
doAnswer(invocation -> {
int indexOfResponseConsumer = 1;
Consumer<GraphQLResponse<ModelWithMetadata<Person>>> onResponse = invocation.getArgument(indexOfResponseConsumer);
ModelMetadata modelMetadata = new ModelMetadata(person1.getId(), false, 1, Temporal.Timestamp.now());
ModelWithMetadata<Person> modelWithMetadata = new ModelWithMetadata<>(person1, modelMetadata);
onResponse.accept(new GraphQLResponse<>(modelWithMetadata, Collections.emptyList()));
return mock(GraphQLOperation.class);
}).when(mockApiPlugin).mutate(any(), any(), any());
HubAccumulator apiInteractionObserver = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.OUTBOX_MUTATION_PROCESSED, 1).start();
// Save person 1
synchronousDataStore.save(person1);
Person result1 = synchronousDataStore.get(Person.class, person1.getId());
assertEquals(person1, result1);
apiInteractionObserver.await();
verify(mockApiCategory).mutate(argThat(getMatcherFor(person1)), any(), any());
// Mock responses for person 2
doAnswer(invocation -> {
int indexOfResponseConsumer = 1;
Consumer<GraphQLResponse<ModelWithMetadata<Person>>> onResponse = invocation.getArgument(indexOfResponseConsumer);
ModelMetadata modelMetadata = new ModelMetadata(person2.getId(), false, 1, Temporal.Timestamp.now());
ModelWithMetadata<Person> modelWithMetadata = new ModelWithMetadata<>(person2, modelMetadata);
onResponse.accept(new GraphQLResponse<>(modelWithMetadata, Collections.emptyList()));
return mock(GraphQLOperation.class);
}).when(mockApiPlugin).mutate(any(), any(), any());
// Do the thing!
synchronousDataStore.stop();
assertRemoteSubscriptionsCancelled();
apiInteractionObserver = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.OUTBOX_MUTATION_PROCESSED, 1).start();
HubAccumulator orchestratorInitObserver = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.READY, 1).start();
// Interact with the DataStore after the stop
synchronousDataStore.save(person2);
// Verify person 2 was published to the cloud
apiInteractionObserver.await();
// Verify the orchestrator started back up and subscriptions are active.
orchestratorInitObserver.await();
assertRemoteSubscriptionsStarted();
// Verify person 1 and 2 are in the DataStore
List<Person> results = synchronousDataStore.list(Person.class);
assertEquals(Arrays.asList(person1, person2), results);
verify(mockApiCategory, atLeastOnce()).mutate(argThat(getMatcherFor(person2)), any(), any());
}
Aggregations