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
}
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);
}
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);
}
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());
}
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);
}
Aggregations