use of com.amplifyframework.testmodels.commentsblog.Post in project amplify-android by aws-amplify.
the class SQLiteStorageAdapterDeleteTest method deleteModelTypeWithPredicateCascades.
/**
* Assert that delete model type with predicate deletes items in
* the SQLite database without violating foreign key constraints.
* @throws DataStoreException On unexpected failure manipulating items in/out of DataStore
*/
@Test
public void deleteModelTypeWithPredicateCascades() throws DataStoreException {
// Create 1 blog owner, which has 3 blogs each, which has 3 posts each.
// Insert 1 blog owner, 3 blogs, 9 posts
Set<String> expected = new HashSet<>();
BlogOwner ownerModel = BlogOwner.builder().name("Blog Owner 1").build();
adapter.save(ownerModel);
for (int blog = 1; blog <= 3; blog++) {
Blog blogModel = Blog.builder().name("Blog " + blog).owner(ownerModel).build();
adapter.save(blogModel);
expected.add(blogModel.getId());
for (int post = 1; post <= 3; post++) {
Post postModel = Post.builder().title("Post " + blog + "-" + post).status(PostStatus.INACTIVE).rating(5).blog(blogModel).build();
adapter.save(postModel);
expected.add(postModel.getId());
}
}
// Observe deletions
TestObserver<String> deleteObserver = adapter.observe().filter(change -> StorageItemChange.Type.DELETE.equals(change.type())).map(StorageItemChange::item).map(Model::getId).test();
// Triggers a delete of all blogs.
// All posts will be deleted by cascade.
adapter.delete(Blog.class, QueryPredicates.all());
// Assert 3 blogs and 9 posts are deleted.
deleteObserver.assertValueCount(12);
assertEquals(expected, new HashSet<>(deleteObserver.values()));
// Get the BlogOwner from the database. Should not have been deleted.
final List<BlogOwner> blogOwners = adapter.query(BlogOwner.class);
assertEquals(Collections.singletonList(ownerModel), blogOwners);
// Get the Blogs and Posts from the database. Should be deleted.
assertTrue(adapter.query(Blog.class).isEmpty());
assertTrue(adapter.query(Post.class).isEmpty());
}
use of com.amplifyframework.testmodels.commentsblog.Post in project amplify-android by aws-amplify.
the class SQLiteStorageAdapterQueryTest method queryFieldsAreBackwardsCompatible.
/**
* Test that new QueryField with explicit model name produces the same result as old QueryField.
* @throws DataStoreException On failure to arrange items into store, or from the query action itself
*/
@Test
public void queryFieldsAreBackwardsCompatible() throws DataStoreException {
BlogOwner blogOwner = BlogOwner.builder().name("Test Dummy").build();
adapter.save(blogOwner);
Blog blog = Blog.builder().name("Blogging for Dummies").owner(blogOwner).build();
adapter.save(blog);
final int numModels = 10;
for (int counter = 0; counter < numModels; counter++) {
final Post post = Post.builder().title("title " + counter).status(PostStatus.INACTIVE).rating(counter).blog(blog).build();
adapter.save(post);
}
// Assert that using QueryField without model name yields same results if there is no column ambiguity
assertEquals(adapter.query(Post.class, Where.matches(field("Post", "title").contains("4"))), adapter.query(Post.class, Where.matches(field("title").contains("4"))));
assertEquals(adapter.query(Post.class, Where.matches(field("Post", "rating").gt(3))), adapter.query(Post.class, Where.matches(field("rating").gt(3))));
}
use of com.amplifyframework.testmodels.commentsblog.Post in project amplify-android by aws-amplify.
the class ObserveQueryExecutorTest method observeQueryReturnsSortedListOfTotalItemsWithInt.
/**
* ObserveQuery returns sorted list of total items with int.
* @throws InterruptedException interrupted exception.
* @throws AmplifyException data store exception.
*/
@Test
public void observeQueryReturnsSortedListOfTotalItemsWithInt() throws InterruptedException, AmplifyException {
CountDownLatch latch = new CountDownLatch(1);
CountDownLatch changeLatch = new CountDownLatch(1);
AtomicInteger count = new AtomicInteger();
List<Post> posts = new ArrayList<>();
for (int counter = 0; counter < 5; counter++) {
final Post post = Post.builder().title(counter + "-title").status(PostStatus.INACTIVE).rating(counter).build();
posts.add(post);
}
int maxRecords = 50;
Consumer<Cancelable> observationStarted = NoOpConsumer.create();
SyncStatus mockSyncStatus = mock(SyncStatus.class);
when(mockSyncStatus.get(any(), any())).thenReturn(false);
Subject<StorageItemChange<? extends Model>> subject = PublishSubject.<StorageItemChange<? extends Model>>create().toSerialized();
Consumer<DataStoreQuerySnapshot<Post>> onQuerySnapshot = value -> {
if (count.get() == 0) {
Assert.assertTrue(value.getItems().contains(posts.get(0)));
latch.countDown();
} else if (count.get() == 1) {
List<Post> sorted = new ArrayList<>(posts);
Collections.sort(sorted, Comparator.comparing(Post::getRating));
assertEquals(sorted, value.getItems());
Assert.assertEquals(11, value.getItems().size());
changeLatch.countDown();
}
count.getAndIncrement();
};
Consumer<DataStoreException> onObservationError = NoOpConsumer.create();
Action onObservationComplete = NoOpAction.create();
SqlQueryProcessor mockSqlQueryProcessor = mock(SqlQueryProcessor.class);
when(mockSqlQueryProcessor.queryOfflineData(eq(Post.class), any(), any())).thenReturn(posts);
when(mockSqlQueryProcessor.modelExists(any(), any())).thenReturn(true);
ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 5);
ObserveQueryExecutor<Post> observeQueryExecutor = new ObserveQueryExecutor<>(subject, mockSqlQueryProcessor, threadPool, mockSyncStatus, new ModelSorter<>(), maxRecords, 2);
List<QuerySortBy> sortBy = new ArrayList<>();
sortBy.add(Post.RATING.ascending());
observeQueryExecutor.observeQuery(Post.class, new ObserveQueryOptions(null, sortBy), observationStarted, onQuerySnapshot, onObservationError, onObservationComplete);
Assert.assertTrue(latch.await(2, TimeUnit.SECONDS));
for (int i = 5; i < 11; i++) {
Post itemChange = Post.builder().title(i + "-title").status(PostStatus.INACTIVE).rating(i).build();
posts.add(itemChange);
subject.onNext(StorageItemChange.<Post>builder().changeId(UUID.randomUUID().toString()).initiator(StorageItemChange.Initiator.SYNC_ENGINE).item(itemChange).patchItem(SerializedModel.create(itemChange, ModelSchema.fromModelClass(Post.class))).modelSchema(ModelSchema.fromModelClass(BlogOwner.class)).predicate(QueryPredicates.all()).type(StorageItemChange.Type.CREATE).build());
}
Assert.assertTrue(changeLatch.await(5, TimeUnit.SECONDS));
}
use of com.amplifyframework.testmodels.commentsblog.Post in project amplify-android by aws-amplify.
the class DataStoreConfigurationTest method testDefaultOverriddenFromConfigurationAndObject.
/**
* When building a configuration from both a config file and a configuration object,
* default values should be overridden, and the provided ones shall be used, instead.
* @throws JSONException While arranging config file JSON
* @throws AmplifyException While building DataStoreConfiguration instances via build(), or when deriving a
* {@link ModelSchema} from a {@link Model} class.
*/
@Test
public void testDefaultOverriddenFromConfigurationAndObject() throws JSONException, AmplifyException {
long expectedSyncIntervalMinutes = 6L;
Long expectedSyncIntervalMs = TimeUnit.MINUTES.toMillis(expectedSyncIntervalMinutes);
Integer expectedSyncMaxRecords = 3;
DummyConflictHandler dummyConflictHandler = new DummyConflictHandler();
DataStoreErrorHandler errorHandler = DefaultDataStoreErrorHandler.instance();
DataStoreSyncExpression ownerSyncExpression = () -> BlogOwner.ID.beginsWith(RandomString.string());
DataStoreSyncExpression postSyncExpression = () -> Post.ID.beginsWith(RandomString.string());
DataStoreConfiguration configObject = DataStoreConfiguration.builder().syncMaxRecords(expectedSyncMaxRecords).conflictHandler(dummyConflictHandler).errorHandler(errorHandler).syncExpression(BlogOwner.class, ownerSyncExpression).syncExpression("Post", postSyncExpression).doSyncRetry(true).build();
JSONObject jsonConfigFromFile = new JSONObject().put(ConfigKey.SYNC_INTERVAL_IN_MINUTES.toString(), expectedSyncIntervalMinutes);
DataStoreConfiguration dataStoreConfiguration = DataStoreConfiguration.builder(jsonConfigFromFile, configObject).build();
assertEquals(expectedSyncIntervalMs, dataStoreConfiguration.getSyncIntervalMs());
assertEquals(expectedSyncMaxRecords, dataStoreConfiguration.getSyncMaxRecords());
assertEquals(DataStoreConfiguration.DEFAULT_SYNC_PAGE_SIZE, dataStoreConfiguration.getSyncPageSize().longValue());
assertTrue(dataStoreConfiguration.getDoSyncRetry());
assertEquals(dummyConflictHandler, dataStoreConfiguration.getConflictHandler());
assertEquals(errorHandler, dataStoreConfiguration.getErrorHandler());
Map<String, DataStoreSyncExpression> expectedSyncExpressions = new HashMap<>();
expectedSyncExpressions.put(BlogOwner.class.getSimpleName(), ownerSyncExpression);
expectedSyncExpressions.put(Post.class.getSimpleName(), postSyncExpression);
assertEquals(expectedSyncExpressions, dataStoreConfiguration.getSyncExpressions());
}
use of com.amplifyframework.testmodels.commentsblog.Post in project amplify-android by aws-amplify.
the class AppSyncClientInstrumentationTest method testAllOperations.
/**
* Tests the operations in AppSyncClient.
* @throws DataStoreException If any call to AppSync endpoint fails to return a response
* @throws AmplifyException On failure to obtain ModelSchema
*/
@Test
@SuppressWarnings("MethodLength")
public void testAllOperations() throws AmplifyException {
ModelSchema blogOwnerSchema = ModelSchema.fromModelClass(BlogOwner.class);
ModelSchema postSchema = ModelSchema.fromModelClass(Post.class);
ModelSchema blogSchema = ModelSchema.fromModelClass(Blog.class);
long startTimeSeconds = TimeUnit.MILLISECONDS.toSeconds(new Date().getTime());
// Create simple model with no relationship
BlogOwner owner = BlogOwner.builder().name("David").build();
ModelWithMetadata<BlogOwner> blogOwnerCreateResult = create(owner, blogOwnerSchema);
BlogOwner actual = blogOwnerCreateResult.getModel();
ModelAssert.assertEqualsIgnoringTimestamps(owner, actual);
assertEquals(new Integer(1), blogOwnerCreateResult.getSyncMetadata().getVersion());
// TODO: BE AWARE THAT THE DELETED PROPERTY RETURNS NULL INSTEAD OF FALSE
assertNull(blogOwnerCreateResult.getSyncMetadata().isDeleted());
assertTrue(blogOwnerCreateResult.getSyncMetadata().getId().endsWith(owner.getId()));
// Subscribe to Blog creations
Observable<GraphQLResponse<ModelWithMetadata<Blog>>> blogCreations = onCreate(blogSchema);
// Now, actually create a Blog
Blog blog = Blog.builder().name("Create test").owner(owner).build();
ModelWithMetadata<Blog> blogCreateResult = create(blog, blogSchema);
// Currently cannot do BlogOwner.justId because it will assign the id to the name field.
// This is being fixed
assertEquals(blog.getId(), blogCreateResult.getModel().getId());
assertEquals(blog.getName(), blogCreateResult.getModel().getName());
assertEquals(blog.getOwner().getId(), blogCreateResult.getModel().getOwner().getId());
assertEquals(new Integer(1), blogCreateResult.getSyncMetadata().getVersion());
assertNull(blogCreateResult.getSyncMetadata().isDeleted());
Temporal.Timestamp createdBlogLastChangedAt = blogCreateResult.getSyncMetadata().getLastChangedAt();
assertNotNull(createdBlogLastChangedAt);
assertTrue(createdBlogLastChangedAt.getSecondsSinceEpoch() > startTimeSeconds);
assertTrue(blogCreateResult.getSyncMetadata().getId().endsWith(blog.getId()));
// TODO: Subscriptions are currently failing. More investigation required to fix this part of the test.
// Validate that subscription picked up the mutation and end the subscription since we're done with.
// TestObserver<ModelWithMetadata<Blog>> blogCreationSubscriber = TestObserver.create();
// blogCreations
// .map(GraphQLResponse::getData)
// .subscribe(blogCreationSubscriber);
// blogCreationSubscriber.assertValue(blogCreateResult);
// Create Posts which Blog hasMany of
Post post1 = Post.builder().title("Post 1").status(PostStatus.ACTIVE).rating(4).blog(blog).build();
Post post2 = Post.builder().title("Post 2").status(PostStatus.INACTIVE).rating(-1).blog(blog).build();
Post post1ModelResult = create(post1, postSchema).getModel();
Post post2ModelResult = create(post2, postSchema).getModel();
// Results only have blog ID so strip out other information from the original post blog
ModelAssert.assertEqualsIgnoringTimestamps(post1.copyOfBuilder().blog(Blog.justId(blog.getId())).build(), post1ModelResult);
ModelAssert.assertEqualsIgnoringTimestamps(post2.copyOfBuilder().blog(Blog.justId(blog.getId())).build(), post2ModelResult);
// Update model
Blog updatedBlog = blog.copyOfBuilder().name("Updated blog").build();
long updateBlogStartTimeSeconds = TimeUnit.MILLISECONDS.toSeconds(new Date().getTime());
ModelWithMetadata<Blog> blogUpdateResult = update(updatedBlog, blogSchema, 1);
assertEquals(updatedBlog.getName(), blogUpdateResult.getModel().getName());
assertEquals(updatedBlog.getOwner().getId(), blogUpdateResult.getModel().getOwner().getId());
assertEquals(updatedBlog.getId(), blogUpdateResult.getModel().getId());
assertEquals(2, blogUpdateResult.getModel().getPosts().size());
assertEquals(new Integer(2), blogUpdateResult.getSyncMetadata().getVersion());
assertNull(blogUpdateResult.getSyncMetadata().isDeleted());
Temporal.Timestamp updatedBlogLastChangedAt = blogUpdateResult.getSyncMetadata().getLastChangedAt();
assertNotNull(updatedBlogLastChangedAt);
assertTrue(updatedBlogLastChangedAt.getSecondsSinceEpoch() > updateBlogStartTimeSeconds);
// Delete one of the posts
ModelWithMetadata<Post> post1DeleteResult = delete(post1, postSchema, 1);
ModelAssert.assertEqualsIgnoringTimestamps(post1.copyOfBuilder().blog(Blog.justId(blog.getId())).build(), post1DeleteResult.getModel());
Boolean isDeleted = post1DeleteResult.getSyncMetadata().isDeleted();
assertEquals(Boolean.TRUE, isDeleted);
// Try to delete a post with a bad version number
List<GraphQLResponse.Error> post2DeleteErrors = deleteExpectingResponseErrors(post2, postSchema, 0);
assertEquals("Conflict resolver rejects mutation.", post2DeleteErrors.get(0).getMessage());
// Run sync on Blogs
// TODO: This is currently a pretty worthless test - mainly for setting a debug point and manually inspecting
// When you call sync with a null lastSync it gives only one entry per object (the latest state)
Iterable<ModelWithMetadata<Blog>> blogSyncResult = sync(api.buildSyncRequest(blogSchema, null, 1000, QueryPredicates.all()));
assertTrue(blogSyncResult.iterator().hasNext());
// Run sync on Posts
// TODO: This is currently a pretty worthless test - mainly for setting a debug point and manually inspecting
// When you call sync with a lastSyncTime it gives you one entry per version of that object which was created
// since that time.
Iterable<ModelWithMetadata<Post>> postSyncResult = sync(api.buildSyncRequest(postSchema, startTimeSeconds, 1000, QueryPredicates.all()));
assertTrue(postSyncResult.iterator().hasNext());
}
Aggregations