Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent resetting finalized forms that modify entities #6460

Merged
merged 4 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package org.odk.collect.android.feature.settings
import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.odk.collect.android.support.StubOpenRosaServer.EntityListItem
import org.odk.collect.android.support.TestDependencies
import org.odk.collect.android.support.pages.AccessControlPage
import org.odk.collect.android.support.pages.FormEntryPage
Expand Down Expand Up @@ -41,16 +40,12 @@ class ResetProjectTest {
}

@Test
fun canResetSavedFormsAndEntities() {
testDependencies.server.addForm("one-question-entity-registration.xml")
testDependencies.server.addForm(
"one-question-entity-update.xml",
listOf(EntityListItem("people.csv"))
)
fun canResetSavedForms() {
seadowg marked this conversation as resolved.
Show resolved Hide resolved
testDependencies.server.addForm("one-question.xml")

rule.withMatchExactlyProject(testDependencies.server.url)
.startBlankForm("One Question Entity Registration")
.fillOutAndFinalize(FormEntryPage.QuestionAndAnswer("Name", "Logan Roy"))
.startBlankForm("One Question")
.fillOutAndFinalize(FormEntryPage.QuestionAndAnswer("what is your age", "34"))

.openProjectSettingsDialog()
.clickSettings()
Expand All @@ -62,11 +57,7 @@ class ResetProjectTest {
.clickOKOnDialog(MainMenuPage())

.clickDrafts()
.assertTextDoesNotExist("One Question Entity Registration")
.pressBack(MainMenuPage())

.startBlankForm("One Question Entity Update")
.assertTextDoesNotExist("Logan Roy")
.assertTextDoesNotExist("One Question")
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import org.odk.collect.androidshared.data.AppState
import org.odk.collect.androidshared.data.getData
import org.odk.collect.forms.Form
import org.odk.collect.forms.instances.Instance
import org.odk.collect.forms.instances.Instance.STATUS_COMPLETE
import org.odk.collect.forms.instances.Instance.STATUS_SUBMISSION_FAILED
import org.odk.collect.metadata.PropertyManager
import org.odk.collect.projects.ProjectDependencyFactory
import java.io.File
Expand Down Expand Up @@ -180,14 +182,18 @@ class InstancesDataService(
}
}

fun deleteAll(projectId: String): Boolean {
fun reset(projectId: String): Boolean {
val projectDependencyModule =
projectDependencyModuleFactory.create(projectId)
val instancesRepository = projectDependencyModule.instancesRepository

return projectDependencyModule.instancesLock.withLock { acquiredLock: Boolean ->
if (acquiredLock) {
instancesRepository.deleteAll()
instancesRepository.all.forEach {
if (it.canDelete()) {
instancesRepository.delete(it.dbId)
}
}
update(projectId)
true
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class ProjectResetter(
private fun resetInstances() {
entitiesRepositoryFactory.create(projectId).clear()

if (!instancesDataService.deleteAll(projectId) ||
if (!instancesDataService.reset(projectId) ||
!deleteFolderContent(storagePaths.instancesDir)
) {
failedResetActions.add(ResetAction.RESET_INSTANCES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import org.odk.collect.android.projects.ProjectDependencyModule
import org.odk.collect.android.utilities.ChangeLocks
import org.odk.collect.androidshared.data.AppState
import org.odk.collect.forms.instances.Instance.STATUS_COMPLETE
import org.odk.collect.forms.instances.Instance.STATUS_INCOMPLETE
import org.odk.collect.forms.instances.Instance.STATUS_INVALID
import org.odk.collect.forms.instances.Instance.STATUS_SUBMISSION_FAILED
import org.odk.collect.forms.instances.Instance.STATUS_SUBMITTED
import org.odk.collect.forms.instances.Instance.STATUS_VALID
import org.odk.collect.formstest.FormFixtures
import org.odk.collect.formstest.InMemFormsRepository
import org.odk.collect.formstest.InMemInstancesRepository
Expand Down Expand Up @@ -105,4 +110,24 @@ class InstancesDataServiceTest {
val result = instancesDataService.sendInstances("projectId")
assertThat(result, equalTo(false))
}

@Test
fun `#reset does not reset instances that can't be deleted before sending`() {
val formsRepository = projectDependencyModule.formsRepository
val form = formsRepository.save(FormFixtures.form())

val instancesRepository = projectDependencyModule.instancesRepository
instancesRepository.save(InstanceFixtures.instance(form = form, canDeleteBeforeSend = false, status = STATUS_INCOMPLETE))
instancesRepository.save(InstanceFixtures.instance(form = form, canDeleteBeforeSend = false, status = STATUS_COMPLETE))
instancesRepository.save(InstanceFixtures.instance(form = form, canDeleteBeforeSend = false, status = STATUS_INVALID))
instancesRepository.save(InstanceFixtures.instance(form = form, canDeleteBeforeSend = false, status = STATUS_VALID))
instancesRepository.save(InstanceFixtures.instance(form = form, canDeleteBeforeSend = false, status = STATUS_SUBMITTED))
instancesRepository.save(InstanceFixtures.instance(form = form, canDeleteBeforeSend = false, status = STATUS_SUBMISSION_FAILED))

instancesDataService.reset(projectDependencyModule.projectId)
val remainingInstances = instancesRepository.all
assertThat(remainingInstances.size, equalTo(2))
assertThat(remainingInstances.any { it.status == STATUS_COMPLETE }, equalTo(true))
assertThat(remainingInstances.any { it.status == STATUS_SUBMISSION_FAILED }, equalTo(true))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ object InstanceFixtures {
displayName: String? = null,
dbId: Long? = null,
form: Form? = null,
deletedDate: Long? = null
deletedDate: Long? = null,
canDeleteBeforeSend: Boolean = true
): Instance {
val instancesDir = TempFiles.createTempDir()
return InstanceUtils.buildInstance("formId", "version", instancesDir.absolutePath)
Expand All @@ -26,7 +27,7 @@ object InstanceFixtures {
}
}
.deletedDate(deletedDate)
.canDeleteBeforeSend(true)
.canDeleteBeforeSend(canDeleteBeforeSend)
.build()
}
}
2 changes: 1 addition & 1 deletion strings/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@
<string name="select_all">Select All</string>
<string name="clear_all">Clear All</string>
<string name="reset_settings">All settings (internal settings, saved settings)</string>
<string name="reset_saved_forms">Saved forms and entities (instances folder, instances database, entities database)</string>
<string name="reset_saved_forms">Saved forms (instances folder, instances database)</string>
<string name="reset_blank_forms">Blank forms (forms folder, forms database, itemsets database)</string>
<string name="reset_layers">Map layers (layers folder)</string>
<string name="reset_cache">Form load cache (.cache folder)</string>
Expand Down