diff --git a/src/rios/core/validation/form.py b/src/rios/core/validation/form.py index fa166d2..f7d41f4 100644 --- a/src/rios/core/validation/form.py +++ b/src/rios/core/validation/form.py @@ -646,6 +646,7 @@ def _check_fields_covered(self, node, cstruct): field['id'] for field in self.instrument['record'] ]) + hide_disable_targets = set() form_fields = set() for pidx, page in enumerate(cstruct['pages']): @@ -666,6 +667,12 @@ def _check_fields_covered(self, node, cstruct): ) form_fields.add(field_id) + for event in element['options'].get('events', []): + if event['action'] in ('hide', 'disable'): + hide_disable_targets.update( + event.get('targets', [field_id]) + ) + missing = instrument_fields - form_fields if missing: raise ValidationError( @@ -684,6 +691,21 @@ def _check_fields_covered(self, node, cstruct): ) ) + required_fields = set([ + field['id'] + for field in self.instrument['record'] + if field.get('required', False) + ]) + hidden_required_fields = required_fields & hide_disable_targets + if hidden_required_fields: + raise ValidationError( + node, + 'There are required fields targetted by hide/disable events:' + ' %s' % ( + ', '.join(sorted(hidden_required_fields)), + ) + ) + def _get_instrument_field_type(self, name, record=None): record = record or self.instrument['record'] for field in record: diff --git a/tests/test_form_validation.py b/tests/test_form_validation.py index 1168a16..6a1ff2c 100644 --- a/tests/test_form_validation.py +++ b/tests/test_form_validation.py @@ -418,3 +418,28 @@ def test_wrong_standard_widget(): else: assert False + +def test_hiding_required_field_top_top(): + instrument = deepcopy(INSTRUMENT) + instrument['record'][1]['required'] = True + validator = Form(instrument=instrument) + form = deepcopy(FORM) + form['pages'][1]['elements'][0]['options']['events'] = [{ + 'trigger': 'true()', + 'action': 'hide', + 'targets': ['boolean_field'], + }] + form['pages'][0]['elements'][5]['options']['events'] = [{ + 'trigger': 'true()', + 'action': 'disable', + }] + try: + validator.deserialize(form) + except ValidationError as exc: + assert_validation_error( + exc, + {'': u'There are required fields targetted by hide/disable events: boolean_field, text_field'}, + ) + else: + assert False +