Search in sources :

Example 1 with Model

use of com.amplifyframework.core.model.Model 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 Model

use of com.amplifyframework.core.model.Model in project amplify-android by aws-amplify.

the class PendingMutationTest method pendingMutationsAreComparable.

/**
 * It is possible to sort pending mutations according to their TimeBasedUUID field.
 * @throws AmplifyException On failure to arrange model schema
 */
@Test
public void pendingMutationsAreComparable() throws AmplifyException {
    // First, create a bunch of pending mutations.
    final List<PendingMutation<? extends Model>> expectedOrder = new ArrayList<>();
    final int desiredQuantity = 10;
    for (int index = 0; index < desiredQuantity; index++) {
        // to make sure the comparator can work across model types
        if (new SecureRandom().nextBoolean()) {
            BlogOwner blogger = BlogOwner.builder().name(String.format(Locale.US, "Blogger #%d", index)).build();
            ModelSchema schema = ModelSchema.fromModelClass(BlogOwner.class);
            expectedOrder.add(PendingMutation.creation(blogger, schema));
        } else {
            Post post = Post.builder().title(String.format(Locale.US, "Title #%d", index)).status(PostStatus.ACTIVE).rating(5).build();
            ModelSchema schema = ModelSchema.fromModelClass(Post.class);
            expectedOrder.add(PendingMutation.creation(post, schema));
        }
    }
    // Okay! Now, shuffle them.
    List<PendingMutation<? extends Model>> shuffled = new ArrayList<>(expectedOrder);
    Collections.shuffle(shuffled, new SecureRandom());
    // Now sort them according to the item comparator, {@link PendingMutation#compareTo(Object)}.
    List<PendingMutation<? extends Model>> actualOrder = new ArrayList<>(shuffled);
    Collections.sort(actualOrder);
    assertEquals(expectedOrder, actualOrder);
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) Post(com.amplifyframework.testmodels.commentsblog.Post) Model(com.amplifyframework.core.model.Model) ArrayList(java.util.ArrayList) SecureRandom(java.security.SecureRandom) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Test(org.junit.Test)

Example 3 with Model

use of com.amplifyframework.core.model.Model in project amplify-android by aws-amplify.

the class InMemoryStorageAdapter method delete.

// item.getClass() -> Class<?>, but type is T. So cast as Class<T> is OK.
@SuppressWarnings("unchecked")
@Override
public <T extends Model> void delete(@NonNull final T item, @NonNull final StorageItemChange.Initiator initiator, @NonNull final QueryPredicate predicate, @NonNull final Consumer<StorageItemChange<T>> onSuccess, @NonNull final Consumer<DataStoreException> onError) {
    final int index = indexOf(item);
    if (index < 0) {
        onError.accept(new DataStoreException("This item was not found in the datastore: " + item.toString(), "Use save() function to create models to store."));
        return;
    }
    Model savedItem = items.remove(index);
    final ModelSchema schema;
    final SerializedModel patchItem;
    try {
        schema = ModelSchema.fromModelClass(item.getClass());
        patchItem = SerializedModel.create(savedItem, schema);
    } catch (AmplifyException schemaBuildFailure) {
        onError.accept(new DataStoreException("Failed to build model schema.", schemaBuildFailure, "Verify your model."));
        return;
    }
    if (!predicate.evaluate(savedItem)) {
        onError.accept(new DataStoreException("Conditional check failed.", "Verify that there is a saved model that matches the provided predicate."));
        return;
    }
    StorageItemChange<T> deletion = StorageItemChange.<T>builder().item((T) savedItem).patchItem(patchItem).modelSchema(schema).type(StorageItemChange.Type.DELETE).predicate(predicate).initiator(initiator).build();
    itemChangeStream.onNext(deletion);
    onSuccess.accept(deletion);
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) DataStoreException(com.amplifyframework.datastore.DataStoreException) AmplifyException(com.amplifyframework.AmplifyException) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) SerializedModel(com.amplifyframework.core.model.SerializedModel)

Example 4 with Model

use of com.amplifyframework.core.model.Model in project amplify-android by aws-amplify.

the class InMemoryStorageAdapter method query.

@Override
public void query(@NonNull String modelName, @NonNull QueryOptions options, @NonNull Consumer<Iterator<? extends Model>> onSuccess, @NonNull Consumer<DataStoreException> onError) {
    final List<Model> result = new ArrayList<>();
    final QueryPredicate predicate = options.getQueryPredicate();
    for (Model item : items) {
        if (modelName.equals(item.getClass().getSimpleName()) && predicate.evaluate(item)) {
            // TODO, add tests for new query method.
            result.add(item);
        }
    }
    onSuccess.accept(result.iterator());
}
Also used : QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) ArrayList(java.util.ArrayList)

Example 5 with Model

use of com.amplifyframework.core.model.Model in project amplify-android by aws-amplify.

the class InMemoryStorageAdapter method save.

@Override
public <T extends Model> void save(@NonNull final T item, @NonNull final StorageItemChange.Initiator initiator, @NonNull final QueryPredicate predicate, @NonNull final Consumer<StorageItemChange<T>> onSuccess, @NonNull final Consumer<DataStoreException> onError) {
    StorageItemChange.Type type = StorageItemChange.Type.CREATE;
    final int index = indexOf(item);
    Model savedItem = null;
    if (index > -1) {
        // There is an existing record with that ID; this is an update.
        type = StorageItemChange.Type.UPDATE;
        savedItem = items.get(index);
        if (!predicate.evaluate(savedItem)) {
            onError.accept(new DataStoreException("Conditional check failed.", "Verify that there is a saved model that matches the provided predicate."));
            return;
        } else {
            items.remove(index);
        }
    }
    final ModelSchema schema;
    final SerializedModel patchItem;
    try {
        schema = ModelSchema.fromModelClass(item.getClass());
        patchItem = SerializedModel.difference(item, savedItem, schema);
    } catch (AmplifyException schemaBuildFailure) {
        onError.accept(new DataStoreException("Failed to build model schema.", schemaBuildFailure, "Verify your model."));
        return;
    }
    items.add(item);
    StorageItemChange<T> change = StorageItemChange.<T>builder().item(item).patchItem(patchItem).modelSchema(schema).type(type).predicate(predicate).initiator(initiator).build();
    itemChangeStream.onNext(change);
    onSuccess.accept(change);
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) DataStoreException(com.amplifyframework.datastore.DataStoreException) AmplifyException(com.amplifyframework.AmplifyException) SerializedModel(com.amplifyframework.core.model.SerializedModel) Model(com.amplifyframework.core.model.Model) SerializedModel(com.amplifyframework.core.model.SerializedModel)

Aggregations

Model (com.amplifyframework.core.model.Model)62 Test (org.junit.Test)37 DataStoreException (com.amplifyframework.datastore.DataStoreException)34 ModelSchema (com.amplifyframework.core.model.ModelSchema)32 SerializedModel (com.amplifyframework.core.model.SerializedModel)30 AmplifyException (com.amplifyframework.AmplifyException)23 Cancelable (com.amplifyframework.core.async.Cancelable)22 Action (com.amplifyframework.core.Action)19 Consumer (com.amplifyframework.core.Consumer)19 StorageItemChange (com.amplifyframework.datastore.storage.StorageItemChange)19 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)19 ArrayList (java.util.ArrayList)19 List (java.util.List)19 SchemaRegistry (com.amplifyframework.core.model.SchemaRegistry)18 RandomModel (com.amplifyframework.testutils.random.RandomModel)17 GraphQLResponse (com.amplifyframework.api.graphql.GraphQLResponse)16 QueryPredicates (com.amplifyframework.core.model.query.predicate.QueryPredicates)16 TimeUnit (java.util.concurrent.TimeUnit)16 Collections (java.util.Collections)15 ObserveQueryOptions (com.amplifyframework.core.model.query.ObserveQueryOptions)13