use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class SqlCommandTest method noFieldsModelSchemaReturnsNoColumnsSqlCommand.
/**
* Test if {@link ModelSchema} with no fields return an expected
* CREATE TABLE SQL command with no columns.
*/
@Test
public void noFieldsModelSchemaReturnsNoColumnsSqlCommand() {
final ModelSchema modelSchema = ModelSchema.builder().fields(Collections.emptyMap()).name("Guitar").build();
final SqlCommand sqlCommand = sqlCommandFactory.createTableFor(modelSchema);
assertEquals("Guitar", sqlCommand.tableName());
assertEquals("CREATE TABLE IF NOT EXISTS `Guitar` ", sqlCommand.sqlStatement());
}
use of com.amplifyframework.core.model.ModelSchema 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));
}
use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class MergerTest method itemIsMergedAfterPendingMutationRemovedFromOutbox.
/**
* When processing a mutation response, the pending mutation should be removed from the outbox, and the mutation
* should be merged to local storage.
* @throws InterruptedException If interrupted while awaiting terminal result in test observer
* @throws AmplifyException On failure to arrange model schema
*/
@Test
public void itemIsMergedAfterPendingMutationRemovedFromOutbox() 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.DELETE, 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> observer = mutationOutbox.remove(pendingMutation.getMutationId()).andThen(merger.merge(new ModelWithMetadata<>(blogOwner, cloudMetadata))).test();
observer.await(REASONABLE_WAIT_TIME, TimeUnit.MILLISECONDS);
observer.assertNoErrors().assertComplete();
// Assert: the item IS deleted from the local store.
// Or in other words, the cloud data WAS merged.
final List<BlogOwner> blogOwnersInStorage = storageAdapter.query(BlogOwner.class);
assertEquals(0, blogOwnersInStorage.size());
}
use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class MutationProcessorTest method canDrainMutationOutboxOnPublicationError.
/**
* If error is caused by AppSync response, then the mutation outbox continues to
* drain without getting blocked.
* @throws DataStoreException On failure to save models
*/
@Test
public void canDrainMutationOutboxOnPublicationError() throws DataStoreException {
ModelSchema schema = schemaRegistry.getModelSchemaForModelClass(BlogOwner.class);
// We will attempt to "sync" 10 models.
final int maxAttempts = 10;
for (int attempt = 0; attempt < maxAttempts; attempt++) {
BlogOwner model = BlogOwner.builder().name("Blogger #" + attempt).build();
synchronousStorageAdapter.save(model);
// Every other model triggers an AppSync error response.
if (attempt % 2 == 0) {
AppSyncMocking.create(appSync).mockErrorResponse(model);
} else {
AppSyncMocking.create(appSync).mockSuccessResponse(model);
}
// Enqueue a creation in the mutation outbox
assertTrue(mutationOutbox.enqueue(PendingMutation.creation(model, schema)).blockingAwait(TIMEOUT_SECONDS, TimeUnit.SECONDS));
}
// Start listening for Mutation Outbox Empty event.
HubAccumulator accumulator = HubAccumulator.create(HubChannel.DATASTORE, isOutboxEmpty(true), 1).start();
// Start draining the outbox.
mutationProcessor.startDrainingMutationOutbox();
accumulator.await();
}
use of com.amplifyframework.core.model.ModelSchema in project amplify-android by aws-amplify.
the class MultiAuthSyncEngineInstrumentationTest method configure.
/**
* Method used to configure each scenario.
* @param modelType The model type.
* @param signInToCognito Does the test scenario require the user to be logged in with user pools.
* @param signInWithOidc Does the test scenario require the user to be logged in with an OIDC provider.
* @param expectedAuthType The auth type that should succeed for the test.
* @throws AmplifyException No expected.
* @throws IOException Not expected.
*/
private void configure(Class<? extends Model> modelType, boolean signInToCognito, boolean signInWithOidc, AuthorizationType expectedAuthType) throws AmplifyException, IOException {
Amplify.addPlugin(new AndroidLoggingPlugin(LogLevel.VERBOSE));
String tag = modelType.getSimpleName();
MultiAuthTestModelProvider modelProvider = MultiAuthTestModelProvider.getInstance(Collections.singletonList(modelType));
SchemaRegistry schemaRegistry = SchemaRegistry.instance();
ModelSchema modelSchema = ModelSchema.fromModelClass(modelType);
schemaRegistry.register(modelType.getSimpleName(), modelSchema);
StrictMode.enable();
Context context = getApplicationContext();
@RawRes int configResourceId = Resources.getRawResourceId(context, "amplifyconfiguration");
AmplifyConfiguration amplifyConfiguration = AmplifyConfiguration.fromConfigFile(context, configResourceId);
readCredsFromConfig(context);
// Setup an auth plugin
CategoryConfiguration authCategoryConfiguration = amplifyConfiguration.forCategoryType(CategoryType.AUTH);
// Turn off persistence so the mobile client's state for one test does not interfere with the others.
try {
authCategoryConfiguration.getPluginConfig("awsCognitoAuthPlugin").getJSONObject("Auth").getJSONObject("Default").put("Persistence", false);
} catch (JSONException exception) {
exception.printStackTrace();
fail();
return;
}
AuthCategory authCategory = new AuthCategory();
AWSCognitoAuthPlugin authPlugin = new AWSCognitoAuthPlugin();
authCategory.addPlugin(authPlugin);
authCategory.configure(authCategoryConfiguration, context);
auth = SynchronousAuth.delegatingTo(authCategory);
if (signInToCognito) {
Log.v(tag, "Test requires signIn.");
AuthSignInResult authSignInResult = auth.signIn(cognitoUser, cognitoPassword);
if (!authSignInResult.isSignInComplete()) {
fail("Unable to complete initial sign-in");
}
}
if (signInWithOidc) {
oidcLogin();
if (token.get() == null) {
fail("Unable to autenticate with OIDC provider");
}
}
// Setup an API
DefaultCognitoUserPoolsAuthProvider cognitoProvider = new DefaultCognitoUserPoolsAuthProvider(authPlugin.getEscapeHatch());
CategoryConfiguration apiCategoryConfiguration = amplifyConfiguration.forCategoryType(CategoryType.API);
ApiAuthProviders apiAuthProviders = ApiAuthProviders.builder().cognitoUserPoolsAuthProvider(cognitoProvider).awsCredentialsProvider(authPlugin.getEscapeHatch()).oidcAuthProvider(token::get).build();
ApiCategory apiCategory = new ApiCategory();
requestInterceptor = new HttpRequestInterceptor(expectedAuthType);
apiCategory.addPlugin(AWSApiPlugin.builder().configureClient("DataStoreIntegTestsApi", okHttpClientBuilder -> okHttpClientBuilder.addInterceptor(requestInterceptor)).apiAuthProviders(apiAuthProviders).build());
apiCategory.configure(apiCategoryConfiguration, context);
api = SynchronousApi.delegatingTo(apiCategory);
// Setup DataStore
DataStoreConfiguration dsConfig = DataStoreConfiguration.builder().errorHandler(exception -> Log.e(tag, "DataStore error handler received an error.", exception)).syncExpression(modelSchema.getName(), () -> Where.id("FAKE_ID").getQueryPredicate()).build();
CategoryConfiguration dataStoreCategoryConfiguration = AmplifyConfiguration.fromConfigFile(context, configResourceId).forCategoryType(CategoryType.DATASTORE);
String databaseName = "IntegTest" + modelType.getSimpleName() + ".db";
SQLiteStorageAdapter sqLiteStorageAdapter = TestStorageAdapter.create(schemaRegistry, modelProvider, databaseName);
AWSDataStorePlugin awsDataStorePlugin = AWSDataStorePlugin.builder().storageAdapter(sqLiteStorageAdapter).modelProvider(modelProvider).apiCategory(apiCategory).authModeStrategy(AuthModeStrategyType.MULTIAUTH).schemaRegistry(schemaRegistry).dataStoreConfiguration(dsConfig).build();
DataStoreCategory dataStoreCategory = new DataStoreCategory();
dataStoreCategory.addPlugin(awsDataStorePlugin);
dataStoreCategory.configure(dataStoreCategoryConfiguration, context);
dataStoreCategory.initialize(context);
dataStore = SynchronousDataStore.delegatingTo(dataStoreCategory);
}
Aggregations