Search in sources :

Example 16 with GraphQLResponse

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);
}
Also used : GraphQLLocation(com.amplifyframework.api.graphql.GraphQLLocation) HashMap(java.util.HashMap) PaginatedResult(com.amplifyframework.api.graphql.PaginatedResult) ArrayList(java.util.ArrayList) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) GraphQLPathSegment(com.amplifyframework.api.graphql.GraphQLPathSegment) QueryType(com.amplifyframework.api.graphql.QueryType) Type(java.lang.reflect.Type) JSONObject(org.json.JSONObject) Test(org.junit.Test)

Example 17 with GraphQLResponse

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);
}
Also used : QueryType(com.amplifyframework.api.graphql.QueryType) Type(java.lang.reflect.Type) HashMap(java.util.HashMap) PaginatedResult(com.amplifyframework.api.graphql.PaginatedResult) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) JSONObject(org.json.JSONObject) Test(org.junit.Test)

Example 18 with GraphQLResponse

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);
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) ModelProvider(com.amplifyframework.core.model.ModelProvider) Pair(android.util.Pair) RunWith(org.junit.runner.RunWith) AppSync(com.amplifyframework.datastore.appsync.AppSync) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) Answer(org.mockito.stubbing.Answer) Consumer(com.amplifyframework.core.Consumer) SubscriptionType(com.amplifyframework.api.graphql.SubscriptionType) Observable(io.reactivex.rxjava3.core.Observable) Map(java.util.Map) Mockito.doAnswer(org.mockito.Mockito.doAnswer) NoOpCancelable(com.amplifyframework.core.async.NoOpCancelable) ModelSchema(com.amplifyframework.core.model.ModelSchema) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) Before(org.junit.Before) DataStoreConfiguration(com.amplifyframework.datastore.DataStoreConfiguration) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Model(com.amplifyframework.core.model.Model) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Completable(io.reactivex.rxjava3.core.Completable) Action(com.amplifyframework.core.Action) RobolectricTestRunner(org.robolectric.RobolectricTestRunner) TimeUnit(java.util.concurrent.TimeUnit) DataStoreException(com.amplifyframework.datastore.DataStoreException) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Cancelable(com.amplifyframework.core.async.Cancelable) Assert.assertFalse(org.junit.Assert.assertFalse) RandomString(com.amplifyframework.testutils.random.RandomString) Temporal(com.amplifyframework.core.model.temporal.Temporal) AmplifyModelProvider(com.amplifyframework.testmodels.commentsblog.AmplifyModelProvider) Collections(java.util.Collections) Mockito.mock(org.mockito.Mockito.mock) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) Consumer(com.amplifyframework.core.Consumer) NoOpCancelable(com.amplifyframework.core.async.NoOpCancelable) NoOpCancelable(com.amplifyframework.core.async.NoOpCancelable) Cancelable(com.amplifyframework.core.async.Cancelable)

Example 19 with GraphQLResponse

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());
}
Also used : ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) JSONObject(org.json.JSONObject) SynchronousDataStore(com.amplifyframework.testutils.sync.SynchronousDataStore) ApiCategory(com.amplifyframework.api.ApiCategory) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) Person(com.amplifyframework.testmodels.personcar.Person) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Example 20 with GraphQLResponse

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());
}
Also used : ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) JSONObject(org.json.JSONObject) SynchronousDataStore(com.amplifyframework.testutils.sync.SynchronousDataStore) ApiCategory(com.amplifyframework.api.ApiCategory) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) Person(com.amplifyframework.testmodels.personcar.Person) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Aggregations

GraphQLResponse (com.amplifyframework.api.graphql.GraphQLResponse)30 Test (org.junit.Test)23 PaginatedResult (com.amplifyframework.api.graphql.PaginatedResult)14 Model (com.amplifyframework.core.model.Model)11 ApiException (com.amplifyframework.api.ApiException)10 Action (com.amplifyframework.core.Action)9 Consumer (com.amplifyframework.core.Consumer)9 ModelWithMetadata (com.amplifyframework.datastore.appsync.ModelWithMetadata)9 JSONObject (org.json.JSONObject)9 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)8 GraphQLRequest (com.amplifyframework.api.graphql.GraphQLRequest)7 RandomString (com.amplifyframework.testutils.random.RandomString)7 AmplifyException (com.amplifyframework.AmplifyException)6 ModelSchema (com.amplifyframework.core.model.ModelSchema)6 ModelMetadata (com.amplifyframework.datastore.appsync.ModelMetadata)6 RandomModel (com.amplifyframework.testutils.random.RandomModel)6 HashMap (java.util.HashMap)6 QueryType (com.amplifyframework.api.graphql.QueryType)5 SubscriptionType (com.amplifyframework.api.graphql.SubscriptionType)5 Cancelable (com.amplifyframework.core.async.Cancelable)5