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());
}
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);
}
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());
}
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;
}
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;
}
Aggregations