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

Add identify-user support #3439

Merged
merged 44 commits into from
Nov 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
3a43e21
Remove Powermock from AuditEventLoggerTest
seadowg Nov 4, 2019
40caeb7
Move audit code into one package
seadowg Nov 5, 2019
89e0318
Add note to state of union about package restructuring
seadowg Nov 5, 2019
4b664e2
Remove test only helpers on AuditEventLogger
seadowg Nov 5, 2019
42d48b5
User is prompted to identify themselves when form has identify-user
seadowg Nov 6, 2019
01a8c24
Don't prompt the user to identify themselves when identify-user=false
seadowg Nov 7, 2019
41b6773
User identity is required to not be empty
seadowg Nov 7, 2019
b1f6cb1
Form is closed if user dismisses identity prompt
seadowg Nov 7, 2019
086d1c4
Set user on AuditEvent during logging
seadowg Nov 7, 2019
f719c4d
Log user to audit.csv
seadowg Nov 11, 2019
6bf2cf6
Add close button to identity prompt dialog
seadowg Nov 11, 2019
09371a3
Try to make FormEntryActivity code a little nicer
seadowg Nov 12, 2019
42041d8
Refactor to allow IdentityPromptViewModel to be initialized on Activi…
seadowg Nov 12, 2019
ff634ef
Test AsyncEventAuditEventWriter instead of task
seadowg Nov 12, 2019
edcefa8
Update upgrade path test for audit event writing
seadowg Nov 12, 2019
b4da96f
Account for null auditConfig in FormController
seadowg Nov 12, 2019
0bfcad8
Stop identity dialog closing on rotate and background
seadowg Nov 18, 2019
1a160a7
Add test for resuming form
seadowg Nov 18, 2019
7ecc006
Escape quotes and commas in audit log user
seadowg Nov 19, 2019
ec2eb39
Use existing escape code
seadowg Nov 19, 2019
4af585a
Use polyfill theme to fix input box colors
seadowg Nov 19, 2019
0020549
Make sure identity prompt works in landscape
seadowg Nov 19, 2019
91ace9e
Fix colors for identity prompt in dark theme
seadowg Nov 19, 2019
0ac57f8
Don't use primary background for identity prompt dialog
seadowg Nov 19, 2019
af32b80
Make sure keyboard opens for identity prompt
seadowg Nov 19, 2019
c21ad72
Prompt user for indentity when editing saved form
seadowg Nov 19, 2019
0cf338b
Remove unused menu
seadowg Nov 19, 2019
b461e7b
Add comment around path into form
seadowg Nov 19, 2019
157f077
Remove simplePressBack from DrawWidgetTest
seadowg Nov 20, 2019
22967e1
Remove simplePressBack
seadowg Nov 20, 2019
f7fe929
Correct dimension name
seadowg Nov 20, 2019
89c1374
Share rotation wait code
seadowg Nov 20, 2019
3c1d203
Fix background of identity prompt on lower API levels
seadowg Nov 20, 2019
0e18c08
Remvoe unneeded parameter form method
seadowg Nov 20, 2019
d26dc90
Add scrolling to form selection
seadowg Nov 20, 2019
c18e444
Rename view model
seadowg Nov 20, 2019
b548c9c
Use primitives instead of object types
seadowg Nov 20, 2019
e06739f
Account for moving backwards disabled setting
seadowg Nov 21, 2019
0ee4868
Don't allow whitespace users
seadowg Nov 25, 2019
6bba809
Make sure toolbar is visible on older API levels
seadowg Nov 25, 2019
9ca2a5c
Rename TextUtils to StringUtils
seadowg Nov 25, 2019
c8deaa7
Switch out CoordinatorLayout from full screen dialog
seadowg Nov 25, 2019
ed4a633
Remove background from dialog theme
seadowg Nov 25, 2019
7b69272
Make sure identity is persisted during rotations
seadowg Nov 26, 2019
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
6 changes: 4 additions & 2 deletions collect_app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,10 @@ dependencies {
exclude group: 'com.google.code.findbugs', module: 'jsr305'
}

androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.3.0-alpha02'
androidTestImplementation("androidx.test.espresso:espresso-intents:3.3.0-alpha02") {
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.2.0'
androidTestImplementation("androidx.test.espresso:espresso-intents:3.2.0") {
exclude group: 'com.android.support', module: 'support-annotations'
exclude group: 'com.google.code.findbugs', module: 'jsr305'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<h:html xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:jr="http://openrosa.org/javarosa" xmlns:odk="http://www.opendatakit.org/xforms"
xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2002/xforms">
<h:head>
<h:title>Identify User False</h:title>
<model>
<instance>
<data id="identify-user-false">
<what_up />
<meta>
<audit />
<instanceID />
</meta>
</data>
</instance>
<bind nodeset="/data/what_up" type="string" />
<bind nodeset="/data/meta/audit" type="binary" odk:identify-user="false" />
<bind nodeset="/data/meta/instanceID" readonly="true()" type="string"
jr:preload="uid" />
</model>
</h:head>
<h:body>
<input ref="/data/what_up">
<label>What up?</label>
</input>
</h:body>
</h:html>
29 changes: 29 additions & 0 deletions collect_app/src/androidTest/assets/forms/identify-user-audit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0"?>
<h:html xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:jr="http://openrosa.org/javarosa" xmlns:odk="http://www.opendatakit.org/xforms"
xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2002/xforms">
<h:head>
<h:title>Identify User</h:title>
<model>
<instance>
<data id="identify-user">
<what_up />
<meta>
<audit />
<instanceID />
</meta>
</data>
</instance>
<bind nodeset="/data/what_up" type="string" />
<bind nodeset="/data/meta/audit" type="binary" odk:identify-user="true" />
<bind nodeset="/data/meta/instanceID" readonly="true()" type="string"
jr:preload="uid" />
</model>
</h:head>
<h:body>
<input ref="/data/what_up">
<label>What up?</label>
</input>
</h:body>
</h:html>
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ public OkDialog clickSavedFormWithDialog(String instanceName) {
onView(withText(instanceName)).perform(click());
return new OkDialog(rule).assertOnPage();
}

public IdentifyUserPromptPage clickOnFormWithIdentityPrompt(String formName) {
onView(withText(formName)).perform(click());
return new IdentifyUserPromptPage(formName, rule).assertOnPage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.odk.collect.android.test.CustomMatchers.withIndex;

public class FillBlankFormPage extends Page<FillBlankFormPage> {
Expand All @@ -24,6 +26,11 @@ public FillBlankFormPage assertOnPage() {
return this;
}

public IdentifyUserPromptPage clickOnFormWithIdentityPrompt(String formName) {
clickOnFormButton(formName);
return new IdentifyUserPromptPage(formName, rule).assertOnPage();
}

public FillBlankFormPage clickOnSortByButton() {
onView(withId(R.id.menu_sort)).perform(click());
return this;
Expand All @@ -43,4 +50,13 @@ public FillBlankFormPage checkIsFormSubtextDisplayed() {
onView(withIndex(withId(R.id.form_subtitle2), 0)).check(matches(isDisplayed()));
return this;
}

public FormEntryPage clickOnForm(String formName) {
clickOnFormButton(formName);
return new FormEntryPage(formName, rule);
}

private void clickOnFormButton(String formName) {
onView(withText(formName)).perform(scrollTo(), click());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import org.odk.collect.android.R;
import org.odk.collect.android.support.ActivityHelpers;

import timber.log.Timber;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.longClick;
Expand Down Expand Up @@ -100,7 +98,7 @@ public FormEntryPage swipeToPreviousQuestion() {
return this;
}

public FormEntryPage clickGoToIconInForm() {
public FormEntryPage clickGoToArrow() {
onView(withId(R.id.menu_goto)).perform(click());
return this;
}
Expand All @@ -115,25 +113,6 @@ public FormEntryPage clickSignatureButton() {
return this;
}

public FormEntryPage waitForRotationToEnd() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Timber.i(e);
}
return this;
}

public FormEntryPage clickIgnoreChanges() {
onView(withText(getInstrumentation().getTargetContext().getString(R.string.do_not_save))).perform(click());
return this;
}

public FormEntryPage simplePressBack() {
Espresso.pressBack();
return this;
}

public FormEntryPage putTextOnIndex(int index, String text) {
onView(withIndex(withClassName(endsWith("Text")), index)).perform(replaceText(text));
return this;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.odk.collect.android.espressoutils.pages;

import androidx.test.rule.ActivityTestRule;

import org.odk.collect.android.R;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.pressImeActionButton;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withHint;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;

public class IdentifyUserPromptPage extends Page<IdentifyUserPromptPage> {

private final String formName;

public IdentifyUserPromptPage(String formName, ActivityTestRule rule) {
super(rule);
this.formName = formName;
}

@Override
public IdentifyUserPromptPage assertOnPage() {
onView(allOf(withText(formName), isDescendantOfA(withId(R.id.toolbar)))).check(matches(isDisplayed()));
onView(withText(getTranslatedString(R.string.enter_identity))).check(matches(isDisplayed()));
return this;
}

public IdentifyUserPromptPage enterIdentity(String identity) {
onView(withHint(getTranslatedString(R.string.identity))).perform(replaceText(identity));
return this;
}

public FormEntryPage clickKeyboardEnter() {
onView(withHint(getTranslatedString(R.string.identity))).perform(pressImeActionButton());
return new FormEntryPage(formName, rule).assertOnPage();
}

public IdentifyUserPromptPage clickKeyboardEnterWithValidationError() {
onView(withHint(getTranslatedString(R.string.identity))).perform(pressImeActionButton());
return this.assertOnPage();
}

public MainMenuPage pressClose() {
onView(withContentDescription(getTranslatedString(R.string.close))).perform(click());
return new MainMenuPage(rule).assertOnPage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import androidx.test.espresso.Espresso;
import androidx.test.espresso.NoMatchingViewException;

import androidx.test.espresso.ViewAction;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.rule.ActivityTestRule;

import org.odk.collect.android.support.actions.RotateAction;

import timber.log.Timber;

import static androidx.test.espresso.Espresso.onView;
Expand All @@ -18,6 +20,7 @@
import static androidx.test.espresso.matcher.RootMatchers.withDecorView;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
Expand Down Expand Up @@ -176,4 +179,26 @@ public T checkIfOptionIsDisabled(int string) {
return (T) this;
}

public <D extends Page<D>> D rotateToLandscape(D destination) {
onView(isRoot()).perform(rotateToLandscape());
waitForRotationToEnd();

return destination.assertOnPage();
}

private static ViewAction rotateToLandscape() {
return new RotateAction();
}

public T waitForRotationToEnd() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Timber.i(e);
}

return (T) this;
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.odk.collect.android.espressoutils.pages;

import androidx.test.rule.ActivityTestRule;

import org.odk.collect.android.R;

public class SaveOrIgnoreDialog<D extends Page<D>> extends Page<SaveOrIgnoreDialog<D>> {

private final String formName;
private final D destination;

public SaveOrIgnoreDialog(String title, D destination, ActivityTestRule rule) {
super(rule);
this.formName = title;
this.destination = destination;
}

@Override
public SaveOrIgnoreDialog assertOnPage() {
String title = getTranslatedString(R.string.exit) + " " + formName;
checkIsTextDisplayed(title);
return this;
}

public D clickSaveChanges() {
clickOnString(R.string.keep_changes);
return destination;
}

public D clickIgnoreChanges() {
clickOnString(R.string.do_not_save);
return destination;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void requestingDeletionOfLastRepeat_deletesLastRepeat() {
@Test
public void requestingDeletionOfFirstRepeatInHierarchy_deletesFirstRepeat() {
FormEntryPage page = new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon();

onView(withId(R.id.list)).check(matches(RecyclerViewMatcher.withListSize(4)));
Expand All @@ -82,7 +82,7 @@ public void requestingDeletionOfFirstRepeatInHierarchy_deletesFirstRepeat() {
@Test
public void requestingDeletionOfMiddleRepeatInHierarchy_deletesMiddleRepeat() {
FormEntryPage page = new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon();

onView(withId(R.id.list)).check(matches(RecyclerViewMatcher.withListSize(4)));
Expand All @@ -100,7 +100,7 @@ public void requestingDeletionOfMiddleRepeatInHierarchy_deletesMiddleRepeat() {
@Test
public void requestingDeletionOfLastRepeatInHierarchy_deletesLastRepeat() {
FormEntryPage page = new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon();

onView(withId(R.id.list)).check(matches(RecyclerViewMatcher.withListSize(4)));
Expand All @@ -118,7 +118,7 @@ public void requestingDeletionOfLastRepeatInHierarchy_deletesLastRepeat() {
@Test
public void requestingDeletionOfFirstRepeatWithFieldList_deletesFirstRepeat() {
new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon()
.clickGoUpIcon()
.clickOnText("repeatGroupFieldList")
Expand All @@ -131,7 +131,7 @@ public void requestingDeletionOfFirstRepeatWithFieldList_deletesFirstRepeat() {
@Test
public void requestingDeletionOfMiddleRepeatWithFieldList_deletesMiddleRepeat() {
new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon()
.clickGoUpIcon()
.clickOnText("repeatGroupFieldList")
Expand All @@ -144,7 +144,7 @@ public void requestingDeletionOfMiddleRepeatWithFieldList_deletesMiddleRepeat()
@Test
public void requestingDeletionOfLastRepeatWithFieldList_deletesLastRepeat() {
new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon()
.clickGoUpIcon()
.clickOnText("repeatGroupFieldList")
Expand All @@ -157,7 +157,7 @@ public void requestingDeletionOfLastRepeatWithFieldList_deletesLastRepeat() {
@Test
public void requestingDeletionOfFirstRepeatWithFieldListInHierarchy_deletesFirstRepeat() {
FormEntryPage page = new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon()
.clickGoUpIcon()
.clickOnText("repeatGroupFieldList");
Expand All @@ -176,7 +176,7 @@ public void requestingDeletionOfFirstRepeatWithFieldListInHierarchy_deletesFirst
@Test
public void requestingDeletionOfMiddleRepeatWithFieldListInHierarchy_deletesMiddleRepeat() {
FormEntryPage page = new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon()
.clickGoUpIcon()
.clickOnText("repeatGroupFieldList");
Expand All @@ -194,7 +194,7 @@ public void requestingDeletionOfMiddleRepeatWithFieldListInHierarchy_deletesMidd
@Test
public void requestingDeletionOfLastRepeatWithFieldListInHierarchy_deletesLastRepeat() {
FormEntryPage page = new FormEntryPage("repeatGroups", activityTestRule)
.clickGoToIconInForm()
.clickGoToArrow()
.clickGoUpIcon()
.clickGoUpIcon()
.clickOnText("repeatGroupFieldList");
Expand Down
Loading