Search in sources :

Example 11 with ApiCategory

use of com.amplifyframework.api.ApiCategory 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 12 with ApiCategory

use of com.amplifyframework.api.ApiCategory in project amplify-android by aws-amplify.

the class AWSDataStorePluginTest method configureAndInitializeInApiModeWithoutApi.

/**
 * Simulate a situation where the user has added the API plugin, but it's
 * either not pushed or exceptions occur while trying to start up the sync processes.
 * The outcome is that the local store should still be available and the
 * host app should not crash.
 * @throws JSONException If an exception occurs while building the JSON configuration.
 * @throws AmplifyException If an exception occurs setting up the mock API
 */
@Ignore("By itself, this test passes! However, it pollutes the context of the test runner, " + " and causes other unrelated tests to fail, as a result. Need to rework this to  " + " ensure that it faithfully cleans up after itself, when done with assertions.")
@Test
public void configureAndInitializeInApiModeWithoutApi() throws JSONException, AmplifyException {
    ApiCategory mockApiCategory = mockApiPluginWithExceptions();
    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));
    Person person1 = createPerson("Test", "Dummy I");
    synchronousDataStore.save(person1);
    assertNotNull(person1.getId());
    Person person1FromDb = synchronousDataStore.get(Person.class, person1.getId());
    assertEquals(person1, person1FromDb);
}
Also used : JSONObject(org.json.JSONObject) SynchronousDataStore(com.amplifyframework.testutils.sync.SynchronousDataStore) ApiCategory(com.amplifyframework.api.ApiCategory) Person(com.amplifyframework.testmodels.personcar.Person) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 13 with ApiCategory

use of com.amplifyframework.api.ApiCategory 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)

Example 14 with ApiCategory

use of com.amplifyframework.api.ApiCategory in project amplify-android by aws-amplify.

the class AWSDataStorePluginTest method mockApiPluginWithExceptions.

/**
 * Almost the same as mockApiCategoryWithGraphQlApi, but it calls the onError callback instead.
 *
 * @return A mock version of the API Category.
 * @throws AmplifyException Throw if an error happens when adding the plugin.
 */
@SuppressWarnings("unchecked")
private static ApiCategory mockApiPluginWithExceptions() throws AmplifyException {
    ApiCategory mockApiCategory = spy(ApiCategory.class);
    ApiPlugin<?> mockApiPlugin = mock(ApiPlugin.class);
    when(mockApiPlugin.getPluginKey()).thenReturn(MOCK_API_PLUGIN_NAME);
    when(mockApiPlugin.getCategoryType()).thenReturn(CategoryType.API);
    doAnswer(invocation -> {
        int indexOfErrorConsumer = 2;
        Consumer<ApiException> onError = invocation.getArgument(indexOfErrorConsumer);
        onError.accept(new ApiException("Fake exception thrown from the API.query method", "Just retry"));
        return null;
    }).when(mockApiPlugin).query(any(GraphQLRequest.class), any(Consumer.class), any(Consumer.class));
    doAnswer(invocation -> {
        int indexOfErrorConsumer = 2;
        Consumer<ApiException> onError = invocation.getArgument(indexOfErrorConsumer);
        onError.accept(new ApiException("Fake exception thrown from the API.mutate method", "Just retry"));
        return null;
    }).when(mockApiPlugin).mutate(any(GraphQLRequest.class), any(Consumer.class), any(Consumer.class));
    doAnswer(invocation -> {
        int indexOfErrorConsumer = 3;
        Consumer<ApiException> onError = invocation.getArgument(indexOfErrorConsumer);
        ApiException apiException = new ApiException("Fake exception thrown from the API.subscribe method", "Just retry");
        onError.accept(apiException);
        return null;
    }).when(mockApiPlugin).subscribe(any(GraphQLRequest.class), any(Consumer.class), any(Consumer.class), any(Consumer.class), any(Action.class));
    mockApiCategory.addPlugin(mockApiPlugin);
    return mockApiCategory;
}
Also used : GraphQLRequest(com.amplifyframework.api.graphql.GraphQLRequest) Action(com.amplifyframework.core.Action) Consumer(com.amplifyframework.core.Consumer) ApiCategory(com.amplifyframework.api.ApiCategory) ApiException(com.amplifyframework.api.ApiException)

Example 15 with ApiCategory

use of com.amplifyframework.api.ApiCategory in project amplify-android by aws-amplify.

the class AWSDataStorePluginTest method mockApiCategoryWithGraphQlApi.

@SuppressWarnings("unchecked")
private ApiCategory mockApiCategoryWithGraphQlApi() throws AmplifyException {
    ApiCategory mockApiCategory = spy(ApiCategory.class);
    ApiPlugin<?> mockApiPlugin = mock(ApiPlugin.class);
    when(mockApiPlugin.getPluginKey()).thenReturn(MOCK_API_PLUGIN_NAME);
    when(mockApiPlugin.getCategoryType()).thenReturn(CategoryType.API);
    ApiEndpointStatusChangeEvent eventData = new ApiEndpointStatusChangeEvent(ApiEndpointStatusChangeEvent.ApiEndpointStatus.REACHABLE, ApiEndpointStatusChangeEvent.ApiEndpointStatus.UNKOWN);
    HubEvent<ApiEndpointStatusChangeEvent> hubEvent = HubEvent.create(ApiChannelEventName.API_ENDPOINT_STATUS_CHANGED, eventData);
    // Make believe that queries return response immediately
    doAnswer(invocation -> {
        // Mock the API emitting an ApiEndpointStatusChangeEvent event.
        Amplify.Hub.publish(HubChannel.API, hubEvent);
        int indexOfResponseConsumer = 1;
        Consumer<GraphQLResponse<PaginatedResult<ModelWithMetadata<Person>>>> onResponse = invocation.getArgument(indexOfResponseConsumer);
        PaginatedResult<ModelWithMetadata<Person>> data = new PaginatedResult<>(Collections.emptyList(), null);
        onResponse.accept(new GraphQLResponse<>(data, Collections.emptyList()));
        return null;
    }).when(mockApiPlugin).query(any(GraphQLRequest.class), any(Consumer.class), any(Consumer.class));
    // Make believe that subscriptions return response immediately
    doAnswer(invocation -> {
        int indexOfStartConsumer = 1;
        Consumer<String> onStart = invocation.getArgument(indexOfStartConsumer);
        GraphQLOperation<?> mockOperation = mock(GraphQLOperation.class);
        doAnswer(opAnswer -> {
            this.subscriptionCancelledCounter.incrementAndGet();
            return null;
        }).when(mockOperation).cancel();
        this.subscriptionStartedCounter.incrementAndGet();
        // Trigger the subscription start event.
        onStart.accept(RandomString.string());
        return mockOperation;
    }).when(mockApiPlugin).subscribe(any(GraphQLRequest.class), any(Consumer.class), any(Consumer.class), any(Consumer.class), any(Action.class));
    mockApiCategory.addPlugin(mockApiPlugin);
    mockApiCategory.configure(new ApiCategoryConfiguration(), getApplicationContext());
    mockApiCategory.initialize(getApplicationContext());
    return mockApiCategory;
}
Also used : ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) Action(com.amplifyframework.core.Action) PaginatedResult(com.amplifyframework.api.graphql.PaginatedResult) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) RandomString(com.amplifyframework.testutils.random.RandomString) GraphQLRequest(com.amplifyframework.api.graphql.GraphQLRequest) Consumer(com.amplifyframework.core.Consumer) ApiEndpointStatusChangeEvent(com.amplifyframework.api.events.ApiEndpointStatusChangeEvent) ApiCategory(com.amplifyframework.api.ApiCategory) ApiCategoryConfiguration(com.amplifyframework.api.ApiCategoryConfiguration)

Aggregations

ApiCategory (com.amplifyframework.api.ApiCategory)21 JSONObject (org.json.JSONObject)9 Test (org.junit.Test)9 SynchronousDataStore (com.amplifyframework.testutils.sync.SynchronousDataStore)8 Context (android.content.Context)7 ApplicationProvider.getApplicationContext (androidx.test.core.app.ApplicationProvider.getApplicationContext)6 Person (com.amplifyframework.testmodels.personcar.Person)6 Before (org.junit.Before)6 RawRes (androidx.annotation.RawRes)5 AWSApiPlugin (com.amplifyframework.api.aws.AWSApiPlugin)5 GraphQLResponse (com.amplifyframework.api.graphql.GraphQLResponse)5 CategoryConfiguration (com.amplifyframework.core.category.CategoryConfiguration)5 ModelWithMetadata (com.amplifyframework.datastore.appsync.ModelWithMetadata)5 HubAccumulator (com.amplifyframework.testutils.HubAccumulator)5 ApiCategoryConfiguration (com.amplifyframework.api.ApiCategoryConfiguration)4 GraphQLRequest (com.amplifyframework.api.graphql.GraphQLRequest)4 Consumer (com.amplifyframework.core.Consumer)4 AndroidLoggingPlugin (com.amplifyframework.logging.AndroidLoggingPlugin)4 ApiEndpointStatusChangeEvent (com.amplifyframework.api.events.ApiEndpointStatusChangeEvent)3 PaginatedResult (com.amplifyframework.api.graphql.PaginatedResult)3