package org.commcare.android.util;
import org.commcare.CommCareApp;
import org.commcare.CommCareApplication;
import org.commcare.CommCareTestApp;
import org.commcare.CommCareTestApplication;
import org.commcare.android.database.app.models.UserKeyRecord;
import org.commcare.android.database.global.models.ApplicationRecord;
import org.commcare.android.mocks.CommCareTaskConnectorFake;
import org.commcare.engine.resource.AppInstallStatus;
import org.commcare.models.database.user.DemoUserBuilder;
import org.commcare.tasks.ResourceEngineTask;
import org.javarosa.core.reference.ReferenceManager;
import org.javarosa.core.reference.ResourceReferenceFactory;
import org.javarosa.core.util.PropertyUtils;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
/**
* Functionality to install an app from local storage, create a test user, log
* into a user session
*
* @author Phillip Mates (pmates@dimagi.com).
*/
public class TestAppInstaller {
private final String username;
private final String password;
private final String resourceFilepath;
public final static CommCareTaskConnectorFake<Object> fakeConnector =
new CommCareTaskConnectorFake<>();
private TestAppInstaller(String resourceFilepath,
String username,
String password) {
this.resourceFilepath = resourceFilepath;
this.username = username;
this.password = password;
}
/**
* Install an app and create / login with a (test) user
*/
public static void installAppAndLogin(String appPath,
String username,
String password) {
installAppAndUser(appPath, username, password);
login(username, password);
}
/**
* Install an app without creating a user
*/
public static void installApp(String appPath) {
storageSetup();
TestAppInstaller appTestInstaller =
new TestAppInstaller(appPath, null, null);
appTestInstaller.installApp();
}
/**
* Install an app with creating a user
*/
public static void installAppAndUser(String appPath,
String username,
String password) {
storageSetup();
TestAppInstaller appTestInstaller =
new TestAppInstaller(
appPath, username, password);
appTestInstaller.installApp();
appTestInstaller.buildTestUser();
}
private static void storageSetup() {
// needed to resolve "jr://resource" type references
ReferenceManager.instance().addReferenceFactory(new ResourceReferenceFactory());
}
private void installApp() {
ApplicationRecord newRecord =
new ApplicationRecord(PropertyUtils.genUUID().replace("-", ""),
ApplicationRecord.STATUS_UNINITIALIZED);
CommCareApp app = new CommCareTestApp(new CommCareApp(newRecord));
ResourceEngineTask<Object> task =
new ResourceEngineTask<Object>(app, -1, false) {
@Override
protected void deliverResult(Object receiver,
AppInstallStatus result) {
}
@Override
protected void deliverUpdate(Object receiver,
int[]... update) {
}
@Override
protected void deliverError(Object receiver,
Exception e) {
throw new RuntimeException("App failed to install during test");
}
};
task.connect(fakeConnector);
task.execute(resourceFilepath);
Robolectric.flushBackgroundThreadScheduler();
Robolectric.flushForegroundThreadScheduler();
}
private void buildTestUser() {
CommCareApp ccApp = CommCareApplication.instance().getCurrentApp();
DemoUserBuilder.buildTestUser(RuntimeEnvironment.application,
ccApp,
username, password);
}
public static void login(String username, String password) {
CommCareApp ccApp = CommCareApplication.instance().getCurrentApp();
((CommCareTestApplication)CommCareApplication.instance()).setCachedUserPassword(password);
UserKeyRecord keyRecord =
UserKeyRecord.getCurrentValidRecordByPassword(ccApp, username, password, true);
CommCareApplication.instance().startUserSession(keyRecord.unWrapKey(password), keyRecord, false);
}
}