Search in sources :

Example 6 with ModelMetadata

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

the class MergerTest method itemWithSameVersionIsNotMerged.

/**
 * If the incoming change has the SAME version as the data currently in the DB, we refuse to update it.
 * The user may have updated the data locally via the DataStore API. So we would clobber it.
 * The version must be strictly HIGHER than the current version, in order for the merge to succeed.
 * @throws DataStoreException On failure to interact with storage during arrange/verify
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 */
@Test
public void itemWithSameVersionIsNotMerged() throws DataStoreException, InterruptedException {
    // Arrange a model and metadata into storage.
    BlogOwner existingModel = BlogOwner.builder().name("Cornelius Daniels").build();
    ModelMetadata existingMetadata = new ModelMetadata(existingModel.getModelName() + "|" + existingModel.getId(), false, 55, Temporal.Timestamp.now());
    storageAdapter.save(existingModel, existingMetadata);
    // Act: try to merge, but specify a LOWER version.
    BlogOwner incomingModel = existingModel.copyOfBuilder().name("Cornelius Daniels, but woke af, now.").build();
    ModelMetadata lowerVersionMetadata = new ModelMetadata(incomingModel.getId(), false, 33, Temporal.Timestamp.now());
    ModelWithMetadata<BlogOwner> modelWithLowerVersionMetadata = new ModelWithMetadata<>(incomingModel, lowerVersionMetadata);
    TestObserver<Void> mergeObserver = merger.merge(modelWithLowerVersionMetadata).test();
    mergeObserver.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS);
    mergeObserver.assertNoErrors().assertComplete();
    // Assert: Joey is still the same old Joey.
    List<BlogOwner> actualBlogOwners = storageAdapter.query(BlogOwner.class);
    assertEquals(1, actualBlogOwners.size());
    assertEquals(existingModel, actualBlogOwners.get(0));
    // And his metadata is the still the same.
    assertEquals(Collections.singletonList(existingMetadata), storageAdapter.query(ModelMetadata.class, Where.id(existingModel.getModelName() + "|" + 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 7 with ModelMetadata

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

the class MergerTest method mergeSaveForExistingItem.

/**
 * Assume there is an item A in the store. We try to merge a save for A.
 * This should succeed, and it should be treated as an update. After the merge,
 * A should have the updates from the merge.
 * @throws DataStoreException On failure to arrange data into store
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 */
@Test
public void mergeSaveForExistingItem() throws DataStoreException, InterruptedException {
    // Arrange: an item is already in the store.
    BlogOwner originalModel = BlogOwner.builder().name("Jameson The Original").build();
    ModelMetadata originalMetadata = new ModelMetadata(originalModel.getModelName() + "|" + originalModel.getId(), false, 1, Temporal.Timestamp.now());
    storageAdapter.save(originalModel, originalMetadata);
    // Act: merge a save.
    BlogOwner updatedModel = originalModel.copyOfBuilder().name("Jameson The New and Improved").build();
    ModelMetadata updatedMetadata = new ModelMetadata(originalMetadata.getId(), false, 2, Temporal.Timestamp.now());
    TestObserver<Void> observer = merger.merge(new ModelWithMetadata<>(updatedModel, updatedMetadata)).test();
    assertTrue(observer.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS));
    observer.assertComplete().assertNoErrors();
    // Assert: the *UPDATED* stuff is in the store, *only*.
    assertEquals(Collections.singletonList(updatedModel), storageAdapter.query(BlogOwner.class));
    assertEquals(Collections.singletonList(updatedMetadata), storageAdapter.query(ModelMetadata.class));
}
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 8 with ModelMetadata

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

the class MergerTest method mergeSaveForNotExistingItem.

/**
 * Assume there is NO item A. Then, we try to merge a save for a
 * item A. This should succeed, with A being in the 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 mergeSaveForNotExistingItem() throws DataStoreException, InterruptedException {
    // Arrange: nothing in the store, to start.
    BlogOwner blogOwner = BlogOwner.builder().name("Jameson").build();
    ModelMetadata metadata = new ModelMetadata(blogOwner.getModelName() + "|" + blogOwner.getId(), false, 1, Temporal.Timestamp.now());
    // Note that storageAdapter.save(...) is NOT called!
    // storageAdapter.save(blogOwner, metadata);
    // Act: merge a creation for an item
    TestObserver<Void> observer = merger.merge(new ModelWithMetadata<>(blogOwner, metadata)).test();
    assertTrue(observer.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS));
    observer.assertNoErrors().assertComplete();
    // Assert: the item & its associated metadata are now in the store.
    assertEquals(Collections.singletonList(blogOwner), storageAdapter.query(BlogOwner.class));
    assertEquals(Collections.singletonList(metadata), storageAdapter.query(ModelMetadata.class));
}
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 9 with ModelMetadata

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

the class MergerTest method itemWithLowerVersionIsNotMerged.

/**
 * An incoming mutation whose model has a LOWER version than an already existing model
 * shall be rejected from the merger.
 * @throws DataStoreException On failure interacting with local store during test arrange/verify.
 * @throws InterruptedException If interrupted while awaiting terminal result in test observer
 */
@Test
public void itemWithLowerVersionIsNotMerged() 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, 55, Temporal.Timestamp.now());
    storageAdapter.save(existingModel, existingMetadata);
    // Act: try to merge, but specify a LOWER version.
    BlogOwner incomingModel = existingModel.copyOfBuilder().name("Cornelius Daniels, but woke af, now.").build();
    ModelMetadata lowerVersionMetadata = new ModelMetadata(incomingModel.getId(), false, 33, Temporal.Timestamp.now());
    ModelWithMetadata<BlogOwner> modelWithLowerVersionMetadata = new ModelWithMetadata<>(existingModel, lowerVersionMetadata);
    TestObserver<Void> mergeObserver = merger.merge(modelWithLowerVersionMetadata).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 10 with ModelMetadata

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

the class MutationProcessorTest method conflictHandlerInvokedForUnhandledConflictError.

/**
 * If the AppSync response to the mutation contains a ConflictUnhandled
 * error in the GraphQLResponse error list, then the user-provided
 * conflict handler should be invoked.
 * @throws DataStoreException On failure to obtain configuration from the provider
 * @throws AmplifyException On failure to build {@link ModelSchema}
 */
@Test
public void conflictHandlerInvokedForUnhandledConflictError() throws AmplifyException {
    // Arrange a user-provided conflict handler.
    CountDownLatch handlerInvocationsRemainingCount = new CountDownLatch(1);
    when(configurationProvider.getConfiguration()).thenReturn(DataStoreConfiguration.builder().conflictHandler((conflictData, onDecision) -> handlerInvocationsRemainingCount.countDown()).build());
    // Save a model, its metadata, and its last sync data.
    BlogOwner model = BlogOwner.builder().name("Exceptional Blogger").build();
    ModelMetadata metadata = new ModelMetadata(model.getModelName() + "|" + model.getId(), false, 1, Temporal.Timestamp.now());
    ModelSchema schema = schemaRegistry.getModelSchemaForModelClass(BlogOwner.class);
    LastSyncMetadata lastSyncMetadata = LastSyncMetadata.baseSyncedAt(schema.getName(), 1_000L);
    synchronousStorageAdapter.save(model, metadata, lastSyncMetadata);
    // Enqueue an update in the mutation outbox
    assertTrue(mutationOutbox.enqueue(PendingMutation.update(model, schema)).blockingAwait(TIMEOUT_SECONDS, TimeUnit.SECONDS));
    // Fields that represent the "server's" understanding of the model state
    Map<String, Object> serverModelData = new HashMap<>();
    serverModelData.put("id", model.getId());
    serverModelData.put("name", "Server blogger name");
    serverModelData.put("_version", 1);
    serverModelData.put("_deleted", false);
    serverModelData.put("_lastChangedAt", 1_000);
    // When AppSync receives that update, have it respond
    // with a ConflictUnhandledError.
    String message = "Conflict resolver rejects mutation.";
    List<GraphQLPathSegment> paths = Collections.singletonList(new GraphQLPathSegment("updateBlogOwner"));
    List<GraphQLLocation> locations = Collections.singletonList(new GraphQLLocation(2, 3));
    Map<String, Object> extensions = new HashMap<>();
    extensions.put("errorType", "ConflictUnhandled");
    extensions.put("data", serverModelData);
    GraphQLResponse.Error error = new GraphQLResponse.Error(message, locations, paths, extensions);
    AppSyncMocking.update(appSync).mockErrorResponse(model, 1, error);
    // Start the mutation processor.
    mutationProcessor.startDrainingMutationOutbox();
    // Wait for the conflict handler to be called.
    Latch.await(handlerInvocationsRemainingCount);
}
Also used : GraphQLLocation(com.amplifyframework.api.graphql.GraphQLLocation) HashMap(java.util.HashMap) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) GraphQLPathSegment(com.amplifyframework.api.graphql.GraphQLPathSegment) CountDownLatch(java.util.concurrent.CountDownLatch) ModelSchema(com.amplifyframework.core.model.ModelSchema) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) ModelMetadata(com.amplifyframework.datastore.appsync.ModelMetadata) Test(org.junit.Test)

Aggregations

ModelMetadata (com.amplifyframework.datastore.appsync.ModelMetadata)29 ModelWithMetadata (com.amplifyframework.datastore.appsync.ModelWithMetadata)23 Test (org.junit.Test)23 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)22 Temporal (com.amplifyframework.core.model.temporal.Temporal)7 GraphQLResponse (com.amplifyframework.api.graphql.GraphQLResponse)6 ModelSchema (com.amplifyframework.core.model.ModelSchema)6 HubAccumulator (com.amplifyframework.testutils.HubAccumulator)4 NonNull (androidx.annotation.NonNull)3 ApiCategory (com.amplifyframework.api.ApiCategory)3 SerializedModel (com.amplifyframework.core.model.SerializedModel)3 Person (com.amplifyframework.testmodels.personcar.Person)3 RandomString (com.amplifyframework.testutils.random.RandomString)3 SynchronousDataStore (com.amplifyframework.testutils.sync.SynchronousDataStore)3 HashMap (java.util.HashMap)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 GraphQLLocation (com.amplifyframework.api.graphql.GraphQLLocation)2 GraphQLPathSegment (com.amplifyframework.api.graphql.GraphQLPathSegment)2 Amplify (com.amplifyframework.core.Amplify)2 Consumer (com.amplifyframework.core.Consumer)2