Skip to content

Commit

Permalink
Merge branch 'getodk:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
spwoodcock authored Mar 22, 2024
2 parents f4afced + 8370877 commit 35e26c1
Show file tree
Hide file tree
Showing 146 changed files with 2,070 additions and 469 deletions.
1 change: 1 addition & 0 deletions .circleci/test_modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ metadata
selfie-camera
draw
printer
lists
2 changes: 1 addition & 1 deletion collect_app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ dependencies {
implementation project(':google-maps')
implementation project(':draw')
implementation project(':printer')
implementation project(':lists')

if (getSecrets().getProperty('MAPBOX_DOWNLOADS_TOKEN', '') != '') {
implementation project(':mapbox')
Expand All @@ -277,7 +278,6 @@ dependencies {
implementation Dependencies.androidx_preference_ktx
implementation Dependencies.androidx_fragment_ktx

implementation Dependencies.android_material
implementation Dependencies.android_flexbox

implementation Dependencies.play_services_maps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.junit.rules.RuleChain;
import org.odk.collect.android.R;
import org.odk.collect.android.support.rules.BlankFormTestRule;
import org.odk.collect.android.support.rules.ResetStateRule;
import org.odk.collect.android.support.rules.TestRuleChain;

import java.util.Collections;
Expand All @@ -31,7 +30,6 @@ public class LikertTest {

@Rule
public RuleChain copyFormChain = TestRuleChain.chain()
.around(new ResetStateRule())
.around(activityTestRule);

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ class SavePointTest {
.let { simulateBatteryDeath() }

// Start blank form and check save point is loaded
rule.fillNewForm("two-question-audit.xml", FormHierarchyPage("Two Question"))
rule.fillNewFormWithSavepoint("two-question-audit.xml")
.clickRecover(FormHierarchyPage("Two Question"))
.assertText("Alexei")
.assertTextDoesNotExist("46")
.pressBack(FormEntryPage("Two Question"))
Expand Down Expand Up @@ -78,7 +79,8 @@ class SavePointTest {
.let { simulateBatteryDeath() }

// Edit instance and check save point is loaded
rule.editForm("two-question-audit.xml", "Two Question")
rule.editFormWithSavepoint("two-question-audit.xml")
.clickRecover(FormHierarchyPage("Two Question"))
.assertText("Alexei")
.assertText("52")
.assertTextDoesNotExist("46")
Expand Down Expand Up @@ -110,10 +112,11 @@ class SavePointTest {
rule.setUpProjectAndCopyForm("two-question-audit.xml", listOf("external_data_10.zip"))
.fillNewForm("two-question-audit.xml", "Two Question")
.answerQuestion("What is your name?", "Alexei")
.let { simulateProcessDeath() }
.killApp()

// Start blank form and check save point is loaded
rule.fillNewForm("two-question-audit.xml", FormHierarchyPage("Two Question"))
rule.fillNewFormWithSavepoint("two-question-audit.xml")
.clickRecover(FormHierarchyPage("Two Question"))
.assertText("Alexei")
.pressBack(FormEntryPage("Two Question"))
.closeSoftKeyboard()
Expand Down Expand Up @@ -150,10 +153,11 @@ class SavePointTest {
rule.editForm("two-question-audit.xml", "Two Question")
.clickGoToStart()
.answerQuestion("What is your name?", "Alexei")
.let { simulateProcessDeath() }
.killApp()

// Edit instance and check save point is loaded
rule.editForm("two-question-audit.xml", "Two Question")
rule.editFormWithSavepoint("two-question-audit.xml")
.clickRecover(FormHierarchyPage("Two Question"))
.assertText("Alexei")
.assertText("52")
.pressBack(FormEntryPage("Two Question"))
Expand Down Expand Up @@ -191,7 +195,7 @@ class SavePointTest {
// Create save point for blank form
rule.fillNewForm("two-question-audit.xml", "Two Question")
.answerQuestion("What is your name?", "Alexei")
.let { simulateProcessDeath() }
.killApp()

// Check editing instance doesn't load save point
rule.editForm("two-question-audit.xml", "Two Question")
Expand All @@ -215,7 +219,7 @@ class SavePointTest {
rule.editForm("two-question-audit.xml", "Two Question")
.clickGoToStart()
.answerQuestion("What is your name?", "Alexei")
.let { simulateProcessDeath() }
.killApp()

// Check starting blank form does not load save point
rule.fillNewForm("two-question-audit.xml", "Two Question")
Expand All @@ -228,13 +232,4 @@ class SavePointTest {
private fun simulateBatteryDeath(): FormEntryActivityTestRule {
return rule.simulateProcessRestart()
}

/**
* Simulate a "process death" case where an app in the background is killed
*/
private fun simulateProcessDeath(): FormEntryActivityTestRule {
return rule.navigateAwayFromActivity()
.destroyActivity()
.simulateProcessRestart()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ class AuditTest {
.startBlankForm("One Question Audit")
.fillOut(FormEntryPage.QuestionAndAnswer("what is your age", "31"))
.killAndReopenApp(rule, MainMenuPage())
.startBlankForm("One Question Audit")
.startBlankFormWithSavepoint("One Question Audit")
.clickRecover(FormEntryPage("One Question Audit"))
.swipeToEndScreen()
.clickFinalize()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void sessionRootTranslatorOrderDoesNotMatter() throws Exception {
final Uri formUri = FormsContract.getUri("DEMO", form.getDbId());

// Load the form in order to populate the ReferenceManager
FormLoaderTask formLoaderTask = new FormLoaderTask(formUri, FormsContract.CONTENT_ITEM_TYPE, null, null, formEntryControllerFactory, mock());
FormLoaderTask formLoaderTask = new FormLoaderTask(formUri, FormsContract.CONTENT_ITEM_TYPE, null, null, formEntryControllerFactory, mock(), mock());
formLoaderTask.executeSynchronously();

final File formXml = new File(formPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void loadSearchFromExternalCSVmultipleTimes() throws Exception {
final Uri formUri = FormsContract.getUri("DEMO", form.getDbId());

// initial load with side effects
FormLoaderTask formLoaderTask = new FormLoaderTask(formUri, FormsContract.CONTENT_ITEM_TYPE, null, null, formEntryControllerFactory, mock());
FormLoaderTask formLoaderTask = new FormLoaderTask(formUri, FormsContract.CONTENT_ITEM_TYPE, null, null, formEntryControllerFactory, mock(), mock());
FormLoaderTask.FECWrapper wrapper = formLoaderTask.executeSynchronously();
Assert.assertNotNull(wrapper);
Assert.assertNotNull(wrapper.getController());
Expand All @@ -84,7 +84,7 @@ public void loadSearchFromExternalCSVmultipleTimes() throws Exception {
long dbLastModified = dbFile.lastModified();

// subsequent load should succeed despite side effects from import
formLoaderTask = new FormLoaderTask(formUri, FormsContract.CONTENT_ITEM_TYPE, null, null, formEntryControllerFactory, mock());
formLoaderTask = new FormLoaderTask(formUri, FormsContract.CONTENT_ITEM_TYPE, null, null, formEntryControllerFactory, mock(), mock());
wrapper = formLoaderTask.executeSynchronously();
Assert.assertNotNull(wrapper);
Assert.assertNotNull(wrapper.getController());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public FormEntryPage startBlankForm(String formName) {
return new FormEntryPage(formName).assertOnPage();
}

public SavepointRecoveryDialogPage startBlankFormWithSavepoint(String formName) {
goToBlankForm(formName);
return new SavepointRecoveryDialogPage().assertOnPage();
}

public AddNewRepeatDialog startBlankFormWithRepeatGroup(String formName, String repeatName) {
goToBlankForm(formName);
return new AddNewRepeatDialog(repeatName).assertOnPage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,19 +496,21 @@ abstract class Page<T : Page<T>> {
}

fun <D : Page<D>> killAndReopenApp(rule: ActivityScenarioLauncherRule, destination: D): D {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
killApp()

// reopen
rule.launch<Activity>(getLaunchIntent())
return destination.assertOnPage()
}

// kill
fun killApp() {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
device.pressRecentApps()
device
.findObject(UiSelector().descriptionContains("Collect"))
.swipeUp(10).also {
CollectHelpers.simulateProcessRestart() // the process is not restarted automatically (probably to keep the test running) so we have simulate it
}

// reopen
rule.launch<Activity>(getLaunchIntent())
return destination.assertOnPage()
}

fun assertNoOptionsMenu(): T {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.odk.collect.android.support.pages

import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.RootMatchers.isDialog
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.odk.collect.strings.R

class SavepointRecoveryDialogPage : Page<SavepointRecoveryDialogPage>() {
override fun assertOnPage(): SavepointRecoveryDialogPage {
val title = getTranslatedString(R.string.savepoint_recovery_dialog_title)
onView(withText(title)).inRoot(isDialog()).check(matches(isDisplayed()))
return this
}

fun <D : Page<D>> clickRecover(destination: D): D {
return this.clickOnButtonInDialog(R.string.recover, destination)
}

fun <D : Page<D>> clickDoNotRecover(destination: D): D {
return this.clickOnButtonInDialog(R.string.do_not_recover, destination)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package org.odk.collect.android.support.rules
import android.app.Activity
import android.app.Application
import android.content.Intent
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import org.junit.rules.ExternalResource
import org.odk.collect.android.activities.FormFillingActivity
import org.odk.collect.android.external.FormsContract
import org.odk.collect.android.formmanagement.FormFillingIntentFactory
import org.odk.collect.android.injection.DaggerUtils
Expand All @@ -17,7 +15,7 @@ import org.odk.collect.android.support.StorageUtils
import org.odk.collect.android.support.pages.FormEntryPage
import org.odk.collect.android.support.pages.FormHierarchyPage
import org.odk.collect.android.support.pages.Page
import org.odk.collect.androidtest.ActivityScenarioExtensions.saveInstanceState
import org.odk.collect.android.support.pages.SavepointRecoveryDialogPage
import timber.log.Timber
import java.io.IOException

Expand Down Expand Up @@ -61,21 +59,22 @@ open class FormEntryActivityTestRule :
return fillNewForm(formFilename, FormEntryPage(formName))
}

fun fillNewFormWithSavepoint(formFilename: String): SavepointRecoveryDialogPage {
intent = createNewFormIntent(formFilename)
scenario = ActivityScenario.launch(intent)
return SavepointRecoveryDialogPage().assertOnPage()
}

fun editForm(formFilename: String, instanceName: String): FormHierarchyPage {
intent = createEditFormIntent(formFilename)
scenario = ActivityScenario.launch(intent)
return FormHierarchyPage(instanceName).assertOnPage()
}

fun navigateAwayFromActivity(): FormEntryActivityTestRule {
scenario.moveToState(Lifecycle.State.STARTED)
scenario.saveInstanceState()
return this
}

fun destroyActivity(): FormEntryActivityTestRule {
scenario.moveToState(Lifecycle.State.DESTROYED)
return this
fun editFormWithSavepoint(formFilename: String): SavepointRecoveryDialogPage {
intent = createEditFormIntent(formFilename)
scenario = ActivityScenario.launch(intent)
return SavepointRecoveryDialogPage().assertOnPage()
}

fun simulateProcessRestart(): FormEntryActivityTestRule {
Expand All @@ -94,8 +93,7 @@ open class FormEntryActivityTestRule :

return FormFillingIntentFactory.newInstanceIntent(
application,
FormsContract.getUri(projectId, form!!.dbId),
FormFillingActivity::class
FormsContract.getUri(projectId, form!!.dbId)
)
}

Expand All @@ -113,8 +111,7 @@ open class FormEntryActivityTestRule :
return FormFillingIntentFactory.editInstanceIntent(
application,
projectId,
instance.dbId,
FormFillingActivity::class
instance.dbId
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import org.odk.collect.android.utilities.ApplicationConstants
import org.odk.collect.android.utilities.FormsRepositoryProvider
import org.odk.collect.android.utilities.InstancesRepositoryProvider
import org.odk.collect.android.utilities.MediaUtils
import org.odk.collect.android.utilities.SavepointsRepositoryProvider
import org.odk.collect.async.Scheduler
import org.odk.collect.audiorecorder.recording.AudioRecorder
import org.odk.collect.location.LocationClient
Expand Down Expand Up @@ -52,6 +53,7 @@ class FormEntryViewModelFactory(
private val autoSendSettingsProvider: AutoSendSettingsProvider,
private val formsRepositoryProvider: FormsRepositoryProvider,
private val instancesRepositoryProvider: InstancesRepositoryProvider,
private val savepointsRepositoryProvider: SavepointsRepositoryProvider,
private val qrCodeCreator: QRCodeCreator,
private val htmlPrinter: HtmlPrinter
) : AbstractSavedStateViewModelFactory(owner, null) {
Expand Down Expand Up @@ -83,7 +85,8 @@ class FormEntryViewModelFactory(
projectsDataService,
formSessionRepository.get(sessionId),
entitiesRepositoryProvider.get(projectId),
instancesRepositoryProvider.get(projectId)
instancesRepositoryProvider.get(projectId),
savepointsRepositoryProvider.get(projectId)
)
}

Expand Down
Loading

0 comments on commit 35e26c1

Please sign in to comment.