Repository: XLSForm/pyxform
Pull request #392 (2019-11-04 11:15:21)

Add identify-user audit attribute
This adds the `identify-user` as defined in [this spec](https://docs.google.com/document/d/1lVObIqvM75tCSA5w8Iu3WropJDQmpE3Cap3GWOepTOY/edit#). The original discussion around this feature is [here](https://forum.opendatakit.org/t/approaches-for-linking-form-instance-changes-to-individuals/20189) on the Forum.


Patch:
diff --git a/pyxform/constants.py b/pyxform/constants.py
index f27f5cf..982587f 100644
--- a/pyxform/constants.py
+++ b/pyxform/constants.py
@@ -94,6 +94,7 @@ LOCATION_PRIORITY = "location-priority"
 LOCATION_MIN_INTERVAL = "location-min-interval"
 LOCATION_MAX_AGE = "location-max-age"
 TRACK_CHANGES = "track-changes"
+IDENTIFY_USER = "identify-user"
 
 # supported bind keywords for which external instances will be created for pulldata function
 EXTERNAL_INSTANCES = ["calculate", "constraint", "readonly", "required", "relevant"]
diff --git a/pyxform/xls2json.py b/pyxform/xls2json.py
index a9ed390..31fb867 100644
--- a/pyxform/xls2json.py
+++ b/pyxform/xls2json.py
@@ -652,6 +652,7 @@ def workbook_to_json(
                     constants.LOCATION_MIN_INTERVAL,
                     constants.LOCATION_MAX_AGE,
                     constants.TRACK_CHANGES,
+                    constants.IDENTIFY_USER,
                 ],
             )
 
@@ -675,6 +676,26 @@ def workbook_to_json(
                         }
                     )
 
+            if constants.IDENTIFY_USER in parameters.keys():
+                if (
+                    parameters[constants.IDENTIFY_USER] != "true"
+                    and parameters[constants.IDENTIFY_USER] != "false"
+                ):
+                    raise PyXFormError(
+                        constants.IDENTIFY_USER + " must be set to true or false: "
+                        "'%s' is an invalid value" % parameters[constants.IDENTIFY_USER]
+                    )
+                else:
+                    new_dict["bind"] = new_dict.get("bind", {})
+                    new_dict["bind"].update(
+                        {
+                            "odk:"
+                            + constants.IDENTIFY_USER: parameters[
+                                constants.IDENTIFY_USER
+                            ]
+                        }
+                    )
+
             location_parameters = (
                 constants.LOCATION_PRIORITY,
                 constants.LOCATION_MIN_INTERVAL,


Test patch:
diff --git a/pyxform/tests_v1/test_audit.py b/pyxform/tests_v1/test_audit.py
index e8bbe51..a9bc544 100644
--- a/pyxform/tests_v1/test_audit.py
+++ b/pyxform/tests_v1/test_audit.py
@@ -186,6 +186,50 @@ class AuditTest(PyxformTestCase):
             error__contains=["track-changes must be set to true or false"],
         )
 
+    def test_audit_identify_user_foo(self):
+        self.assertPyxformXform(
+            name="meta_audit",
+            md="""
+            | survey |        |          |                   |
+            |        | type   |   name   | parameters        |
+            |        | audit  |   audit  | identify-user=foo |
+            """,
+            errored=True,
+            error__contains=["identify-user must be set to true or false"],
+        )
+
+    def test_audit_identify_user_true(self):
+        self.assertPyxformXform(
+            name="meta_audit",
+            md="""
+            | survey |        |          |                    |
+            |        | type   |   name   | parameters         |
+            |        | audit  |   audit  | identify-user=true |
+            """,
+            xml__contains=[
+                "<meta>",
+                "<audit/>",
+                "</meta>",
+                '<bind nodeset="/meta_audit/meta/audit" type="binary" odk:identify-user="true"/>',
+            ],
+        )
+
+    def test_audit_identify_user_false(self):
+        self.assertPyxformXform(
+            name="meta_audit",
+            md="""
+            | survey |        |          |                    |
+            |        | type   |   name   | parameters         |
+            |        | audit  |   audit  | identify-user=false |
+            """,
+            xml__contains=[
+                "<meta>",
+                "<audit/>",
+                "</meta>",
+                '<bind nodeset="/meta_audit/meta/audit" type="binary" odk:identify-user="false"/>',
+            ],
+        )
+
     def test_audit_location_track_changes(self):
         self.assertPyxformXform(
             name="meta_audit",