Skip to content
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
2 changes: 2 additions & 0 deletions pyxform/xls2json.py
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,8 @@ def workbook_to_json(
"type": "calculate",
}
)
# Allow ${instanceID} reference for longitudinal / entities workflows.
element_names.update(("instanceID",))

if "instance_name" in settings:
# Automatically add an instanceName element:
Expand Down
150 changes: 150 additions & 0 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,156 @@ def test_instance_name_from_reference__name_not_found__error(self):
],
)

def test_instance_id__exists_in_survey_meta_by_default(self):
"""Should find an instanceID child in the survey-level meta element."""
md = """
| survey |
| | type | name | label |
| | text | q1 | Q1 |
"""
self.assertPyxformXform(
md=md,
xml__xpath_match=[
"""
/h:html/h:head/x:model/x:instance/x:test_name/x:meta/x:instanceID
""",
"""
/h:html/h:head/x:model/x:bind[
@nodeset='/test_name/meta/instanceID'
and @type='string'
and @readonly='true()'
and @jr:preload='uid'
]
""",
],
)

def test_instance_id__bind_can_be_modified_with_setting(self):
"""Should find that the instance_id bind can be changed via instance_id setting."""
md = """
| settings |
| | instance_id |
| | x |

| survey |
| | type | name | label |
| | text | q1 | Q1 |
"""
self.assertPyxformXform(
md=md,
xml__xpath_match=[
"""
/h:html/h:head/x:model/x:instance/x:test_name/x:meta/x:instanceID
""",
"""
/h:html/h:head/x:model/x:bind[
@nodeset='/test_name/meta/instanceID'
and @type='string'
and @readonly='true()'
and @jr:preload='x'
]
""",
],
)

def test_instance_id__can_be_excluded_with_omit_instanceID__no_meta(self):
"""Should find that instanceID can be excluded with omit_instanceID setting.."""
md = """
| settings |
| | omit_instanceID |
| | yes |

| survey |
| | type | name | label |
| | text | q1 | Q1 |
"""
self.assertPyxformXform(
md=md,
xml__xpath_match=[
# The meta block is not emitted if it would be empty.
"""
/h:html/h:head/x:model/x:instance/x:test_name[not(./x:meta)]
""",
"""
/h:html/h:head/x:model[not(./x:bind[@nodeset='/test_name/meta/instanceID'])]
""",
],
)

def test_instance_id__can_be_excluded_with_omit_instanceID__with_meta(self):
"""Should find that instanceID can be excluded with omit_instanceID setting.."""
md = """
| settings |
| | omit_instanceID | instance_name |
| | yes | x |

| survey |
| | type | name | label |
| | text | q1 | Q1 |
"""
self.assertPyxformXform(
md=md,
xml__xpath_match=[
"""
/h:html/h:head/x:model/x:instance/x:test_name/x:meta[not(./x:instanceID)]
""",
"""
/h:html/h:head/x:model[not(./x:bind[@nodeset='/test_name/meta/instanceID'])]
""",
],
)

def test_instance_id__can_be_used_as_reference_variable(self):
"""Should find that ${instanceID} resolves to the survey-level meta child."""
md = """
| survey |
| | type | name | label | calculation | read_only |
| | text | q1 | ${instanceID} | | |
| | text | q2 | Q2 | ${instanceID} | yes |
"""
self.assertPyxformXform(
md=md,
xml__xpath_match=[
"""
/h:html/h:head/x:model/x:instance/x:test_name/x:meta/x:instanceID
""",
"""
/h:html/h:body/x:input[@ref='/test_name/q1']/x:label/x:output[
@value=' /test_name/meta/instanceID '
]
""",
"""
/h:html/h:head/x:model/x:bind[
@nodeset='/test_name/q2'
and @type='string'
and @readonly='true()'
and @calculate=' /test_name/meta/instanceID '
]
""",
],
)

def test_instance_id__can_be_used_as_reference_variable__error(self):
"""Should find that ${instanceID} resolves to the survey-level meta child."""
md = """
| settings |
| | omit_instanceID |
| | yes |

| survey |
| | type | name | label | calculation | read_only |
| | text | q1 | ${instanceID} | | |
"""
self.assertPyxformXform(
md=md,
errored=True,
error__contains=[
ErrorCode.PYREF_003.value.format(
sheet="survey", column="label", row=2, q="instanceID"
),
],
)


class TestNamespaces(PyxformTestCase):
"""
Expand Down