Search in sources :

Example 21 with ModelWithMetadata

use of com.amplifyframework.datastore.appsync.ModelWithMetadata in project amplify-android by aws-amplify.

the class MergerTest method mergeDeletionForNotExistingItem.

/**
 * Assume there is NOT an item in the store. Then, we try to
 * merge a mutation to delete item A. This should succeed, since
 * there was no work to be performed (it was already deleted.) After
 * the merge, there should STILL be no matching item in the store.
 * @throws DataStoreException On failure to query results for assertions
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 */
@Test
public void mergeDeletionForNotExistingItem() throws DataStoreException, InterruptedException {
    // Arrange, to start, there are no items matching the incoming deletion request.
    BlogOwner blogOwner = BlogOwner.builder().name("Jameson").build();
    // Note that storageAdapter.save(...) does NOT happen!
    // storageAdapter.save(blogOwner, new ModelMetadata(blogOwner.getId(), false, 1, Time.now()));
    // Act: try to merge a deletion that refers to an item not in the store
    ModelMetadata deletionMetadata = new ModelMetadata(blogOwner.getId(), true, 1, Temporal.Timestamp.now());
    TestObserver<Void> observer = merger.merge(new ModelWithMetadata<>(blogOwner, deletionMetadata)).test();
    assertTrue(observer.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS));
    observer.assertNoErrors().assertComplete();
    // Assert: there is still nothing in the store.
    assertEquals(0, storageAdapter.query(BlogOwner.class).size());
}
Also used : ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Example 22 with ModelWithMetadata

use of com.amplifyframework.datastore.appsync.ModelWithMetadata in project amplify-android by aws-amplify.

the class MergerTest method itemWithoutVersionIsNotMerged.

/**
 * Gray-box, we know that "no version" evaluates to a version of 0.
 * So, this test should always behave like {@link #itemWithLowerVersionIsNotMerged()}.
 * But, it the inputs to the system are technically different, so it is
 * a distinct test in terms of system input/output.
 * @throws DataStoreException On failure to interact with storage during arrange/verification
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 */
@Test
public void itemWithoutVersionIsNotMerged() throws DataStoreException, InterruptedException {
    // Arrange a model and metadata into storage.
    BlogOwner existingModel = BlogOwner.builder().name("Cornelius Daniels").build();
    ModelMetadata existingMetadata = new ModelMetadata(existingModel.getId(), false, 1, Temporal.Timestamp.now());
    storageAdapter.save(existingModel, existingMetadata);
    // Act: try to merge, but don't specify a version in the metadata being used to merge.
    BlogOwner incomingModel = existingModel.copyOfBuilder().name("Cornelius Daniels, but woke af, now.").build();
    ModelMetadata metadataWithoutVersion = new ModelMetadata(incomingModel.getId(), null, null, null);
    ModelWithMetadata<BlogOwner> incomingModelWithMetadata = new ModelWithMetadata<>(existingModel, metadataWithoutVersion);
    TestObserver<Void> mergeObserver = merger.merge(incomingModelWithMetadata).test();
    mergeObserver.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS);
    mergeObserver.assertNoErrors().assertComplete();
    // Assert: Joey is still the same old Joey.
    assertEquals(Collections.singletonList(existingModel), storageAdapter.query(BlogOwner.class));
    // And his metadata is the still the same.
    assertEquals(Collections.singletonList(existingMetadata), storageAdapter.query(ModelMetadata.class, Where.id(existingModel.getId())));
}
Also used : ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Example 23 with ModelWithMetadata

use of com.amplifyframework.datastore.appsync.ModelWithMetadata in project amplify-android by aws-amplify.

the class MergerTest method itemIsNotMergedWhenOutboxHasPendingMutation.

/**
 * When an item comes into the merger to be merged,
 * if there is a pending mutation in the outbox, for a model of the same ID,
 * then that item shall NOT be merged.
 * @throws DataStoreException On failure to arrange data into store
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 * @throws AmplifyException On failure to arrange model schema
 */
@Test
public void itemIsNotMergedWhenOutboxHasPendingMutation() throws AmplifyException, InterruptedException {
    // Arrange: some model with a well known ID exists on the system.
    // We pretend that the user has recently updated it via the DataStore update() API.
    String knownId = RandomString.string();
    BlogOwner blogOwner = BlogOwner.builder().name("Jameson").id(knownId).build();
    ModelMetadata localMetadata = new ModelMetadata(blogOwner.getId(), false, 1, Temporal.Timestamp.now());
    storageAdapter.save(blogOwner, localMetadata);
    ModelSchema schema = ModelSchema.fromModelClass(BlogOwner.class);
    PendingMutation<BlogOwner> pendingMutation = PendingMutation.instance(blogOwner, schema, PendingMutation.Type.CREATE, QueryPredicates.all());
    TestObserver<Void> enqueueObserver = mutationOutbox.enqueue(pendingMutation).test();
    enqueueObserver.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS);
    enqueueObserver.assertNoErrors().assertComplete();
    // Act: now, cloud sync happens, and the sync engine tries to apply an update
    // for the same model ID, into the store. According to the cloud, this same
    // item should be DELETED.
    ModelMetadata cloudMetadata = new ModelMetadata(knownId, true, 2, Temporal.Timestamp.now());
    TestObserver<Void> mergeObserver = merger.merge(new ModelWithMetadata<>(blogOwner, cloudMetadata)).test();
    mergeObserver.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS);
    mergeObserver.assertNoErrors().assertComplete();
    // Assert: the item is NOT deleted from the local store.
    // The original is still there.
    // Or in other words, the cloud data was NOT merged.
    final List<BlogOwner> blogOwnersInStorage = storageAdapter.query(BlogOwner.class);
    assertEquals(1, blogOwnersInStorage.size());
    assertEquals(blogOwner, blogOwnersInStorage.get(0));
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) RandomString(com.amplifyframework.testutils.random.RandomString) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Example 24 with ModelWithMetadata

use of com.amplifyframework.datastore.appsync.ModelWithMetadata in project amplify-android by aws-amplify.

the class MergerTest method orphanedItemIsNotMerged.

/**
 * Assume item A is dependent on item B, but the remote store has an
 * orphaned item A without item B. Then, we try to merge a save for a
 * item A. This should gracefully fail, with A not being in the local
 * store, at the end.
 * @throws DataStoreException On failure to query results for assertions
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 */
@Test
public void orphanedItemIsNotMerged() throws DataStoreException, InterruptedException {
    // Arrange: an item and its parent are not in the local store
    BlogOwner badOwner = BlogOwner.builder().name("Raphael").build();
    Blog orphanedBlog = Blog.builder().name("How Not To Save Blogs").owner(badOwner).build();
    ModelMetadata metadata = new ModelMetadata(orphanedBlog.getId(), false, 1, Temporal.Timestamp.now());
    // Enforce foreign key constraint on in-memory storage adapter
    doThrow(SQLiteConstraintException.class).when(inMemoryStorageAdapter).save(eq(orphanedBlog), any(), any(), any(), any());
    // Act: merge a creation for an item
    TestObserver<Void> observer = merger.merge(new ModelWithMetadata<>(orphanedBlog, metadata)).test();
    assertTrue(observer.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS));
    observer.assertNoErrors().assertComplete();
    // Assert: orphaned model was not merged locally
    final List<Blog> blogsInStorage = storageAdapter.query(Blog.class);
    assertTrue(blogsInStorage.isEmpty());
}
Also used : ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Blog(com.amplifyframework.testmodels.commentsblog.Blog) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Example 25 with ModelWithMetadata

use of com.amplifyframework.datastore.appsync.ModelWithMetadata in project amplify-android by aws-amplify.

the class OrchestratorTest method setup.

/**
 * Setup mocks and other common elements.
 * @throws AmplifyException Not expected.
 */
@SuppressWarnings("unchecked")
@Before
public void setup() throws AmplifyException {
    ShadowLog.stream = System.out;
    // Arrange: create a BlogOwner
    susan = BlogOwner.builder().name("Susan Quimby").build();
    // SYNC_QUERIES_READY indicates that the sync queries have completed.
    orchestratorInitObserver = HubAccumulator.create(HubChannel.DATASTORE, DataStoreChannelEventName.SYNC_QUERIES_READY, 1).start();
    ModelMetadata metadata = new ModelMetadata(susan.getId(), false, 1, Temporal.Timestamp.now());
    ModelWithMetadata<BlogOwner> modelWithMetadata = new ModelWithMetadata<>(susan, metadata);
    // Mock behaviors from for the API category
    mockApi = mock(GraphQLBehavior.class);
    ApiMocking.mockSubscriptionStart(mockApi);
    ApiMocking.mockSuccessfulMutation(mockApi, susan.getId(), modelWithMetadata);
    ApiMocking.mockSuccessfulQuery(mockApi, modelWithMetadata);
    AppSyncClient appSync = AppSyncClient.via(mockApi);
    localStorageAdapter = InMemoryStorageAdapter.create();
    ModelProvider modelProvider = SimpleModelProvider.withRandomVersion(BlogOwner.class);
    SchemaRegistry schemaRegistry = SchemaRegistry.instance();
    schemaRegistry.clear();
    schemaRegistry.register(modelProvider.models());
    orchestrator = new Orchestrator(modelProvider, schemaRegistry, localStorageAdapter, appSync, DataStoreConfiguration::defaults, () -> Orchestrator.State.SYNC_VIA_API, true);
}
Also used : GraphQLBehavior(com.amplifyframework.api.graphql.GraphQLBehavior) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) AppSyncClient(com.amplifyframework.datastore.appsync.AppSyncClient) ModelProvider(com.amplifyframework.core.model.ModelProvider) SimpleModelProvider(com.amplifyframework.datastore.model.SimpleModelProvider) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) Before(org.junit.Before)

Aggregations

ModelWithMetadata (com.amplifyframework.datastore.appsync.ModelWithMetadata)35 ModelMetadata (com.amplifyframework.datastore.appsync.ModelMetadata)25 Test (org.junit.Test)22 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)21 GraphQLResponse (com.amplifyframework.api.graphql.GraphQLResponse)13 ModelSchema (com.amplifyframework.core.model.ModelSchema)10 Temporal (com.amplifyframework.core.model.temporal.Temporal)10 Consumer (com.amplifyframework.core.Consumer)9 Model (com.amplifyframework.core.model.Model)9 SerializedModel (com.amplifyframework.core.model.SerializedModel)9 SchemaRegistry (com.amplifyframework.core.model.SchemaRegistry)8 HubEvent (com.amplifyframework.hub.HubEvent)8 Completable (io.reactivex.rxjava3.core.Completable)8 DataStoreException (com.amplifyframework.datastore.DataStoreException)7 AppSync (com.amplifyframework.datastore.appsync.AppSync)7 HubChannel (com.amplifyframework.hub.HubChannel)7 List (java.util.List)7 NonNull (androidx.annotation.NonNull)6 Amplify (com.amplifyframework.core.Amplify)6 ModelProvider (com.amplifyframework.core.model.ModelProvider)6