use of com.amplifyframework.testutils.HubAccumulator in project amplify-android by aws-amplify.
the class SyncProcessorTest method dataStoreHubEventsTriggered.
/**
* During a base sync, there are a series of events that should be emitted.
* This test verifies that these events are published via Amplify Hub depending
* on actions takes for each available model.
* @throws DataStoreException Not expected.
* @throws InterruptedException Not expected.
*/
@Test
public void dataStoreHubEventsTriggered() throws DataStoreException, InterruptedException {
// Arrange - BEGIN
int expectedModelCount = Arrays.asList(Post.class, BlogOwner.class).size();
// Collects one syncQueriesStarted event.
HubAccumulator syncStartAccumulator = createAccumulator(syncQueryStartedForModels(modelCount), 1);
// Collects one syncQueriesReady event.
HubAccumulator syncQueryReadyAccumulator = createAccumulator(forEvent(DataStoreChannelEventName.SYNC_QUERIES_READY), 1);
// Collects one modelSynced event for each model.
HubAccumulator modelSyncedAccumulator = createAccumulator(forEvent(DataStoreChannelEventName.MODEL_SYNCED), expectedModelCount);
// Add a couple of seed records so they can be deleted/updated.
storageAdapter.save(DRUM_POST.getModel());
storageAdapter.save(BLOGGER_ISLA.getModel());
// Mock sync query results for a couple of models.
AppSyncMocking.sync(appSync).mockSuccessResponse(Post.class, DELETED_DRUM_POST).mockSuccessResponse(BlogOwner.class, BLOGGER_ISLA, BLOGGER_JAMESON);
// Start the accumulators.
syncQueryReadyAccumulator.start();
syncStartAccumulator.start();
modelSyncedAccumulator.start();
TestObserver<ModelWithMetadata<? extends Model>> hydrationObserver = TestObserver.create();
// Arrange - END
// Act: kickoff sync.
syncProcessor.hydrate().subscribe(hydrationObserver);
// Check - BEGIN
// Verify that sync completes.
assertTrue(hydrationObserver.await(OP_TIMEOUT_MS, TimeUnit.MILLISECONDS));
hydrationObserver.assertNoErrors();
hydrationObserver.assertComplete();
// Verify that syncQueriesStarted was emitted once.
assertEquals(1, syncStartAccumulator.await((int) OP_TIMEOUT_MS, TimeUnit.MILLISECONDS).size());
// Verify that syncQueriesReady was emitted once.
assertEquals(1, syncQueryReadyAccumulator.await((int) OP_TIMEOUT_MS, TimeUnit.MILLISECONDS).size());
// Get the list of modelSynced events captured.
List<HubEvent<?>> hubEvents = modelSyncedAccumulator.await((int) OP_TIMEOUT_MS, TimeUnit.MILLISECONDS);
// Verify that [number of events] = [number of models]
assertEquals(expectedModelCount, hubEvents.size());
ModelSyncedEvent expectedBlogOwnerCounts = new ModelSyncedEvent("BlogOwner", true, 1, 1, 0);
ModelSyncedEvent expectedPostCounts = new ModelSyncedEvent("Post", true, 0, 0, 1);
// For each event (excluding system models), verify the desired count.
for (HubEvent<?> event : hubEvents) {
ModelSyncedEvent eventData = (ModelSyncedEvent) event.getData();
assertTrue(eventData.isFullSync());
assertFalse(eventData.isDeltaSync());
String eventModel = eventData.getModel();
switch(eventModel) {
case "BlogOwner":
// One BlogOwner added and one updated.
assertEquals(expectedBlogOwnerCounts, eventData);
break;
case "Post":
// One post deleted.
assertEquals(expectedPostCounts, eventData);
break;
default:
// Exclude system models
if (!SYSTEM_MODEL_NAMES.contains(eventModel)) {
ModelSyncedEvent otherCounts = new ModelSyncedEvent(eventModel, true, 0, 0, 0);
assertEquals(otherCounts, eventData);
}
}
}
// Check - END
}
use of com.amplifyframework.testutils.HubAccumulator in project amplify-android by aws-amplify.
the class MutationProcessorTest method canDrainMutationOutbox.
/**
* Tests the {@link MutationProcessor#startDrainingMutationOutbox()}. After this method
* is called, any content in the {@link MutationOutbox} should be published via the {@link AppSync}
* and then removed.
* @throws DataStoreException On failure to interact with storage adapter during arrangement
* and verification
*/
@Test
public void canDrainMutationOutbox() throws DataStoreException {
// We will attempt to "sync" this model.
BlogOwner tony = BlogOwner.builder().name("Tony Daniels").build();
synchronousStorageAdapter.save(tony);
// Arrange a cooked response from AppSync.
AppSyncMocking.create(appSync).mockSuccessResponse(tony);
// Start listening for publication events.
HubAccumulator accumulator = HubAccumulator.create(HubChannel.DATASTORE, isProcessed(tony), 1).start();
ModelSchema schema = schemaRegistry.getModelSchemaForModelClass(BlogOwner.class);
PendingMutation<BlogOwner> createTony = PendingMutation.creation(tony, schema);
assertTrue(mutationOutbox.enqueue(createTony).blockingAwait(TIMEOUT_SECONDS, TimeUnit.SECONDS));
// Act! Start draining the outbox.
mutationProcessor.startDrainingMutationOutbox();
// Assert: the event was published
assertEquals(1, accumulator.await().size());
// And that it is no longer in the outbox.
assertFalse(mutationOutbox.hasPendingMutation(tony.getId()));
// And that it was passed to AppSync for publication.
verify(appSync).create(eq(tony), any(), any(), any());
}
use of com.amplifyframework.testutils.HubAccumulator in project amplify-android by aws-amplify.
the class MutationProcessorTest method outboxStatusIsPublishedToHubOnProcess.
/**
* Processing a mutation should publish current outbox status.
*/
@Test
public void outboxStatusIsPublishedToHubOnProcess() {
BlogOwner raphael = BlogOwner.builder().name("Raphael Kim").build();
ModelSchema schema = schemaRegistry.getModelSchemaForModelClass(BlogOwner.class);
PendingMutation<BlogOwner> createRaphael = PendingMutation.creation(raphael, schema);
// Mock up a response from AppSync and enqueue a mutation.
AppSyncMocking.create(appSync).mockSuccessResponse(raphael);
assertTrue(mutationOutbox.enqueue(createRaphael).blockingAwait(TIMEOUT_SECONDS, TimeUnit.SECONDS));
// Start listening for publication events.
// outbox should be empty after processing its only mutation
HubAccumulator statusAccumulator = HubAccumulator.create(HubChannel.DATASTORE, isOutboxEmpty(true), 1).start();
// Start draining the outbox which has one mutation enqueued,
// and make sure that outbox status is published to hub.
mutationProcessor.startDrainingMutationOutbox();
statusAccumulator.await();
}
use of com.amplifyframework.testutils.HubAccumulator in project amplify-android by aws-amplify.
the class MutationProcessorTest method hubEventPublishedForPublicationError.
/**
* If the AppSync response to the mutation contains not-empty GraphQLResponse error
* list without any ConflictUnhandled error, then
* {@link DataStoreChannelEventName#OUTBOX_MUTATION_FAILED} event is published via Hub.
* @throws DataStoreException On failure to save model and metadata
*/
@Test
public void hubEventPublishedForPublicationError() throws DataStoreException {
// Save a model, its metadata, and its last sync data.
BlogOwner model = BlogOwner.builder().name("Average Joe").build();
ModelMetadata metadata = new ModelMetadata(model.getModelName() + "|" + model.getId(), false, 1, Temporal.Timestamp.now());
ModelSchema schema = schemaRegistry.getModelSchemaForModelClass(BlogOwner.class);
synchronousStorageAdapter.save(model, metadata);
// Enqueue an update in the mutation outbox
assertTrue(mutationOutbox.enqueue(PendingMutation.update(model, schema)).blockingAwait(TIMEOUT_SECONDS, TimeUnit.SECONDS));
// When AppSync receives that update, have it respond with an error.
AppSyncMocking.update(appSync).mockErrorResponse(model, 1);
// Start listening for publication events.
HubAccumulator errorAccumulator = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.OUTBOX_MUTATION_FAILED, 1).start();
// Start the mutation processor and wait for hub event.
mutationProcessor.startDrainingMutationOutbox();
errorAccumulator.await();
}
use of com.amplifyframework.testutils.HubAccumulator in project amplify-android by aws-amplify.
the class OrchestratorTest method itemsPlacedInStorageArePublishedToNetwork.
/**
* When an item is placed into storage, a cascade of
* things happen which should ultimately result in a mutation call
* to the API category, with an {@link MutationType} corresponding to the type of
* modification that was made to the storage.
* @throws AmplifyException On failure to load model schema into registry
*/
// Casting ? in HubEvent<?> to PendingMutation<? extends Model>
@SuppressWarnings("unchecked")
@Test
public void itemsPlacedInStorageArePublishedToNetwork() throws AmplifyException {
// Arrange: orchestrator is running
orchestrator.start().test();
orchestratorInitObserver.await(10, TimeUnit.SECONDS);
HubAccumulator accumulator = HubAccumulator.create(HubChannel.DATASTORE, isProcessed(susan), 1).start();
// Act: Put BlogOwner into storage, and wait for it to complete.
SynchronousStorageAdapter.delegatingTo(localStorageAdapter).save(susan);
// Assert that the event is published out to the API
assertEquals(Collections.singletonList(susan), Observable.fromIterable(accumulator.await(10, TimeUnit.SECONDS)).map(HubEvent::getData).map(data -> (OutboxMutationEvent<BlogOwner>) data).map(OutboxMutationEvent::getElement).map(OutboxMutationEvent.OutboxMutationEventElement::getModel).toList().blockingGet());
assertTrue(orchestrator.stop().blockingAwait(5, TimeUnit.SECONDS));
}
Aggregations