Search in sources :

Example 1 with HubAccumulator

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
}
Also used : ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) Post(com.amplifyframework.testmodels.commentsblog.Post) Model(com.amplifyframework.core.model.Model) HubEvent(com.amplifyframework.hub.HubEvent) ModelSyncedEvent(com.amplifyframework.datastore.events.ModelSyncedEvent) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) RandomString(com.amplifyframework.testutils.random.RandomString) Test(org.junit.Test)

Example 2 with HubAccumulator

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());
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) Test(org.junit.Test)

Example 3 with HubAccumulator

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();
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) Test(org.junit.Test)

Example 4 with HubAccumulator

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();
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Example 5 with HubAccumulator

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));
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) AmplifyException(com.amplifyframework.AmplifyException) MutationType(com.amplifyframework.api.graphql.MutationType) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) ModelProvider(com.amplifyframework.core.model.ModelProvider) DataStoreChannelEventName(com.amplifyframework.datastore.DataStoreChannelEventName) RunWith(org.junit.runner.RunWith) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) SynchronousStorageAdapter(com.amplifyframework.datastore.storage.SynchronousStorageAdapter) Observable(io.reactivex.rxjava3.core.Observable) TestHubEventFilters.isProcessed(com.amplifyframework.datastore.syncengine.TestHubEventFilters.isProcessed) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) HubEvent(com.amplifyframework.hub.HubEvent) Before(org.junit.Before) DataStoreConfiguration(com.amplifyframework.datastore.DataStoreConfiguration) Amplify(com.amplifyframework.core.Amplify) HubChannel(com.amplifyframework.hub.HubChannel) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) AppSyncClient(com.amplifyframework.datastore.appsync.AppSyncClient) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Completable(io.reactivex.rxjava3.core.Completable) Mockito.times(org.mockito.Mockito.times) Logger(com.amplifyframework.logging.Logger) Mockito.verify(org.mockito.Mockito.verify) RobolectricTestRunner(org.robolectric.RobolectricTestRunner) TimeUnit(java.util.concurrent.TimeUnit) GraphQLBehavior(com.amplifyframework.api.graphql.GraphQLBehavior) InMemoryStorageAdapter(com.amplifyframework.datastore.storage.InMemoryStorageAdapter) Temporal(com.amplifyframework.core.model.temporal.Temporal) ShadowLog(org.robolectric.shadows.ShadowLog) ApiMocking(com.amplifyframework.testutils.mocks.ApiMocking) Collections(java.util.Collections) SimpleModelProvider(com.amplifyframework.datastore.model.SimpleModelProvider) Assert.assertEquals(org.junit.Assert.assertEquals) Mockito.mock(org.mockito.Mockito.mock) HubEvent(com.amplifyframework.hub.HubEvent) HubAccumulator(com.amplifyframework.testutils.HubAccumulator) Test(org.junit.Test)

Aggregations

HubAccumulator (com.amplifyframework.testutils.HubAccumulator)30 Test (org.junit.Test)27 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)21 ModelSchema (com.amplifyframework.core.model.ModelSchema)7 SerializedModel (com.amplifyframework.core.model.SerializedModel)5 ModelMetadata (com.amplifyframework.datastore.appsync.ModelMetadata)5 ModelWithMetadata (com.amplifyframework.datastore.appsync.ModelWithMetadata)5 JSONObject (org.json.JSONObject)5 Ignore (org.junit.Ignore)5 ApiCategory (com.amplifyframework.api.ApiCategory)4 SynchronousDataStore (com.amplifyframework.testutils.sync.SynchronousDataStore)4 GraphQLResponse (com.amplifyframework.api.graphql.GraphQLResponse)3 HubEvent (com.amplifyframework.hub.HubEvent)3 Blog (com.amplifyframework.testmodels.commentsblog.Blog)3 RandomString (com.amplifyframework.testutils.random.RandomString)3 Before (org.junit.Before)3 AmplifyException (com.amplifyframework.AmplifyException)2 Model (com.amplifyframework.core.model.Model)2 HubChannel (com.amplifyframework.hub.HubChannel)2 Person (com.amplifyframework.testmodels.personcar.Person)2