use of com.amplifyframework.testmodels.commentsblog.BlogOwner in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method enqueueIsSynchronized.
/**
* When two creations for the same model are enqueued, the second should fail. This is similar to
* {@link #existingCreationIncomingCreationYieldsError}, except that the Completable's from the two enqueue calls
* are concatenated into the same stream. The second enqueue should not check if an item exists in the queue
* until the first enqueue is completed.
* @throws InterruptedException If interrupted while awaiting terminal result in test observer
*/
@Test
public void enqueueIsSynchronized() throws InterruptedException {
// Arrange an existing creation mutation
BlogOwner modelInExistingMutation = BlogOwner.builder().name("The Real Papa Tony").build();
PendingMutation<BlogOwner> firstCreation = PendingMutation.creation(modelInExistingMutation, schema);
PendingMutation<BlogOwner> secondCreation = PendingMutation.creation(modelInExistingMutation, schema);
TestObserver<Void> enqueueObserver = mutationOutbox.enqueue(firstCreation).andThen(mutationOutbox.enqueue(secondCreation)).test();
// Assert: caused a failure.
enqueueObserver.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
enqueueObserver.assertError(throwable -> throwable instanceof DataStoreException);
}
use of com.amplifyframework.testmodels.commentsblog.BlogOwner in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method mutationEnqueuedIfExistingMutationIsInFlight.
/**
* Ordinarily, a DELETE would remote a CREATE, in front of it. But if that
* create is marked in flight, we can't remove it. We have to enqueue the new
* mutation.
*/
@Test
public void mutationEnqueuedIfExistingMutationIsInFlight() {
// Arrange an existing mutation.
BlogOwner joe = BlogOwner.builder().name("Joe").build();
PendingMutation<BlogOwner> creation = PendingMutation.creation(joe, schema);
mutationOutbox.enqueue(creation).andThen(mutationOutbox.markInFlight(creation.getMutationId())).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
// Now, look at what happens when we enqueue a new mutation.
PendingMutation<BlogOwner> deletion = PendingMutation.deletion(joe, schema);
mutationOutbox.enqueue(deletion).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
PendingMutation<? extends Model> next = mutationOutbox.peek();
assertNotNull(next);
assertEquals(creation, next);
mutationOutbox.remove(next.getMutationId()).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
next = mutationOutbox.peek();
assertNotNull(next);
assertEquals(deletion, next);
mutationOutbox.remove(next.getMutationId()).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
assertNull(mutationOutbox.peek());
}
use of com.amplifyframework.testmodels.commentsblog.BlogOwner in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method hasPendingMutationReturnsTrueForExistingModelMutation.
/**
* When there is a pending mutation for a particular model ID
* {@link MutationOutbox#hasPendingMutation(String)} must say "yes!".
*/
@Test
public void hasPendingMutationReturnsTrueForExistingModelMutation() {
String modelId = RandomString.string();
BlogOwner joe = BlogOwner.builder().name("Joe").id(modelId).build();
TimeBasedUuid mutationId = TimeBasedUuid.create();
PendingMutation<BlogOwner> pendingMutation = PendingMutation.instance(mutationId, joe, schema, PendingMutation.Type.CREATE, QueryPredicates.all());
mutationOutbox.enqueue(pendingMutation).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
assertTrue(mutationOutbox.hasPendingMutation(modelId));
assertFalse(mutationOutbox.hasPendingMutation(mutationId.toString()));
}
use of com.amplifyframework.testmodels.commentsblog.BlogOwner in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method existingUpdateIncomingDeletionOverwritesExisting.
/**
* When there is already an existing update, and then a deletion comes in, we should
* use the deletion, not the update. No sense in updating the record if you're just going to
* delete it.
* @throws DataStoreException On failure to query storage to inspect mutation records after test action
*/
@Test
public void existingUpdateIncomingDeletionOverwritesExisting() throws DataStoreException {
BlogOwner joe = BlogOwner.builder().name("Original Joe").build();
PendingMutation<BlogOwner> exitingUpdate = PendingMutation.update(joe, schema);
String existingUpdateId = exitingUpdate.getMutationId().toString();
mutationOutbox.enqueue(exitingUpdate).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
PendingMutation<BlogOwner> incomingDeletion = PendingMutation.deletion(joe, schema);
String incomingDeletionId = incomingDeletion.getMutationId().toString();
mutationOutbox.enqueue(incomingDeletion).blockingAwait(TIMEOUT_MS, TimeUnit.MILLISECONDS);
// The original mutation ID is preserved.
List<PendingMutation.PersistentRecord> existingMutationRecords = storage.query(PersistentRecord.class, Where.id(existingUpdateId));
assertEquals(1, existingMutationRecords.size());
// The new ID was discarded ....
List<PendingMutation.PersistentRecord> incomingMutationRecords = storage.query(PersistentRecord.class, Where.id(incomingDeletionId));
assertEquals(0, incomingMutationRecords.size());
// HOWEVER,
// The stored mutation has the original ID, but it has become a deletion, not an update
assertEquals(PendingMutation.Type.DELETE, converter.fromRecord(existingMutationRecords.get(0)).getMutationType());
// Able to get next mutation, it has the original ID
// The model data doesn't really matter, since it only matches on model ID, anyway.
// Importantly, the type is NOT update, but instead has become a deletion.
assertEquals(PendingMutation.instance(exitingUpdate.getMutationId(), joe, schema, PendingMutation.Type.DELETE, QueryPredicates.all()), mutationOutbox.peek());
}
use of com.amplifyframework.testmodels.commentsblog.BlogOwner in project amplify-android by aws-amplify.
the class PersistentMutationOutboxTest method existingUpdateIncomingUpdateWithoutConditionRewritesExistingMutation.
/**
* When there is an existing update mutation, and a new update mutation comes in,
* then we need to remove any existing mutations for that modelId and create the new one.
* @throws DataStoreException On failure to query storage for current mutations state
* @throws InterruptedException If interrupted while awaiting terminal result in test observer
*/
@Test
public void existingUpdateIncomingUpdateWithoutConditionRewritesExistingMutation() throws DataStoreException, InterruptedException {
// Arrange an existing update mutation
BlogOwner modelInExistingMutation = BlogOwner.builder().name("Papa Tony").build();
PendingMutation<BlogOwner> existingUpdate = PendingMutation.update(modelInExistingMutation, schema);
String existingUpdateId = existingUpdate.getMutationId().toString();
mutationOutbox.enqueue(existingUpdate).blockingAwait();
// Act: try to enqueue a new update mutation when there already is one
BlogOwner modelInIncomingMutation = modelInExistingMutation.copyOfBuilder().name("Tony Jr.").build();
PendingMutation<BlogOwner> incomingUpdate = PendingMutation.update(modelInIncomingMutation, schema);
String incomingUpdateId = incomingUpdate.getMutationId().toString();
TestObserver<Void> enqueueObserver = mutationOutbox.enqueue(incomingUpdate).test();
// Assert: OK. The new mutation is accepted
enqueueObserver.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
enqueueObserver.assertComplete();
// Assert: the existing mutation has been removed
assertRecordCountForMutationId(existingUpdateId, 0);
// And the new one has been added to the queue
assertRecordCountForMutationId(incomingUpdateId, 1);
// Ensure the new one is in storage.
PendingMutation<BlogOwner> storedMutation = converter.fromRecord(getPendingMutationRecordFromStorage(incomingUpdateId).get(0));
// This is the name from the second model, not the first!!
assertEquals(modelInIncomingMutation.getName(), storedMutation.getMutatedItem().getName());
// The mutation in the outbox is the incoming one.
assertEquals(incomingUpdate, mutationOutbox.peek());
}
Aggregations