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

Remove empty instanceDir if a user quits the identity dialog #6020

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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 @@ -7,13 +7,15 @@ import org.junit.Rule
import org.junit.Test
import org.junit.rules.RuleChain
import org.junit.runner.RunWith
import org.odk.collect.android.support.StorageUtils
import org.odk.collect.android.support.StorageUtils.getAuditLogForFirstInstance
import org.odk.collect.android.support.pages.FormEntryPage
import org.odk.collect.android.support.pages.FormHierarchyPage
import org.odk.collect.android.support.pages.IdentifyUserPromptPage
import org.odk.collect.android.support.pages.MainMenuPage
import org.odk.collect.android.support.rules.CollectTestRule
import org.odk.collect.android.support.rules.TestRuleChain
import java.io.File
import java.io.IOException

@RunWith(AndroidJUnit4::class)
Expand Down Expand Up @@ -78,13 +80,15 @@ class IdentifyUserTest {
}

@Test
fun openingForm_andPressingBack_returnsToMainMenu() {
fun openingForm_andPressingBack_returnsToMainMenuAndDoesNotLeaveAnEmptyInstanceDir() {
rule.startAtMainMenu()
.copyForm(IDENTIFY_USER_AUDIT_FORM)
.clickFillBlankForm()
.clickOnFormWithIdentityPrompt("Identify User")
.closeSoftKeyboard()
.pressBack(MainMenuPage())

assertThat(File(StorageUtils.getInstancesDirPath()).listFiles().size, equalTo(0))
}

@Test
Expand All @@ -110,12 +114,14 @@ class IdentifyUserTest {
}

@Test
fun openingForm_andPressingCloseCross_returnsToMainMenu() {
fun openingForm_andPressingCloseCross_returnsToMainMenuAndDoesNotLeaveAnEmptyInstanceDir() {
rule.startAtMainMenu()
.copyForm(IDENTIFY_USER_AUDIT_FORM)
.clickFillBlankForm()
.clickOnFormWithIdentityPrompt("Identify User")
.pressClose()

assertThat(File(StorageUtils.getInstancesDirPath()).listFiles().size, equalTo(0))
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ private void setupViewModels(FormEntryViewModelFactory formEntryViewModelFactory

identityPromptViewModel.isFormEntryCancelled().observe(this, isFormEntryCancelled -> {
if (isFormEntryCancelled) {
identityPromptViewModel.exit();
exit();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import androidx.lifecycle.ViewModel;

import org.odk.collect.android.javarosawrapper.FormController;
import org.odk.collect.android.utilities.FileUtils;

public class IdentityPromptViewModel extends ViewModel {

Expand All @@ -20,6 +21,7 @@ public class IdentityPromptViewModel extends ViewModel {

private String identity = "";
private String formName;
private String instanceFolder;

public IdentityPromptViewModel() {
updateRequiresIdentity();
Expand All @@ -28,6 +30,7 @@ public IdentityPromptViewModel() {
public void formLoaded(@NonNull FormController formController) {
this.formName = formController.getFormTitle();
this.auditEventLogger = formController.getAuditEventLogger();
this.instanceFolder = formController.getInstanceFile().getParent();
updateRequiresIdentity();
}

Expand Down Expand Up @@ -72,4 +75,8 @@ private static boolean userIsValid(String user) {
public String getFormTitle() {
return formName;
}

public void exit() {
FileUtils.purgeMediaPath(instanceFolder);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if there's more of a shared place we can handle this clean up. It looks like you can't call FormSaveViewModel#ignoreChanges in this scenario as the FormSaveViewModel won't know about the FormController yet.

Where does this instance folder actually get created?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this instance folder actually get created?

It's here https://github.com/getodk/collect/blob/master/collect_app/src/main/java/org/odk/collect/android/activities/FormFillingActivity.java#L1960

I'm wondering if there's more of a shared place we can handle this clean up.

I was also thinking about that and I'm aware of the fact that this solution is maybe not perfect but I wasn't able to find a better one. If there is a form that requires identity we don't even save formController before passing it formControllerAvailable so it's not available in other places to read the dir parth and remove.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could pull a chunk of the code in FormSaveViewModel#ignoreChanges out into a use case that can be called in both places? Thinking about that

I'm actually wondering whether if the clean up code in ignoreChanges should just be called whenever we end form filling? It might be that we could start thinking of FormSessionRepository more like one of our data services and move logic like that in there (it could be triggered from clear for example).

Maybe I'm thinking about this incorrectly, but the bug doesn't feel high priority enough to not take these opportunities to restructure while fixing it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FormSaveViewModel as the name suggest is responsible for saving-related operations. using it in this case where we don't even enter the form-filling view sounds a little bit weird to me. Do you really think it would be a better place?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was more meaning the shared code would move out FormSaveViewModel to a separate use case rather than using it in both places.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.File;
import java.io.IOException;

@RunWith(AndroidJUnit4.class)
public class IdentityPromptViewModelTest {

@Test
public void done_setsUserOnAuditEventLogger() {
public void done_setsUserOnAuditEventLogger() throws IOException {
FormController formController = mock(FormController.class);
AuditEventLogger auditEventLogger = mock(AuditEventLogger.class);
when(formController.getAuditEventLogger()).thenReturn(auditEventLogger);
when(formController.getInstanceFile()).thenReturn(File.createTempFile("instance", ".xml"));

IdentityPromptViewModel viewModel = new IdentityPromptViewModel();

Expand Down