class TestFormModel(unittest.TestCase): def setUp(self): self.dbm = Mock(spec=DatabaseManager) q1 = UniqueIdField('clinic', name="entity_question", code="ID", label="What is associated entity") q2 = TextField(name="question1_Name", code="Q1", label="What is your name", defaultValue="some default value", constraints=[TextLengthConstraint(5, 10)], required=False) q3 = IntegerField( name="Father's age", code="Q2", label="What is your Father's Age", constraints=[NumericRangeConstraint(min=15, max=120)], required=False) q4 = SelectField(name="Color", code="Q3", label="What is your favourite color", options=[("RED", 'a'), ("YELLOW", 'b')], required=False) q5 = TextField(name="Desc", code="Q4", label="Description", required=False) self.event_time_field_code = "Q6" q6 = DateField(name="Event time", code=self.event_time_field_code, label="Event time field", date_format="%m.%d.%Y", required=False) q7 = GeoCodeField(name="My Location", code="loc", label="Geo Location Field", required=False) self.form_model = FormModel(self.dbm, name="aids", label="Aids form_model", form_code="1", fields=[q1, q2, q3, q4, q5, q6, q7]) self.form_model_patch = patch( 'mangrove.form_model.form_model.FormModel') self.form_model_document_patch = patch( 'mangrove.form_model.form_model.FormModelDocument') def tearDown(self): try: self.form_model_patch.stop() self.form_model_document_patch.stop() except Exception: pass def test_should_validate_for_valid_integer_value(self): answers = {"ID": "1", "Q2": "16"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertTrue(len(errors) == 0) def test_should_return_error_for_invalid_integer_value(self): answers = {"id": "1", "Q2": "200"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertEqual(len(errors), 1) self.assertEqual( {'Q2': "Answer 200 for question Q2 is greater than allowed."}, errors) self.assertEqual(OrderedDict([('ID', '1')]), cleaned_answers) self.assertTrue( isinstance(self.form_model.validation_exception[0], ex.AnswerTooBigException)) self.assertEqual(len(self.form_model.validation_exception), 1) def test_should_return_error_if_exceeding_value_of_the_word_field_limit( self): answers = {"id": "1", "Q1": "TextThatLongerThanAllowed"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertEqual(len(errors), 1) self.assertEqual( { 'Q1': 'Answer TextThatLongerThanAllowed for question Q1 is longer than allowed.' }, errors) self.assertEqual(OrderedDict([('ID', '1')]), cleaned_answers) self.assertEqual(len(self.form_model.validation_exception), 1) self.assertTrue( isinstance(self.form_model.validation_exception[0], ex.AnswerTooLongException)) def test_should_return_error_if_answering_with_invalid_geo_format(self): answers = {"id": "1", "loc": "127.178057 -78.007789"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertEqual(len(errors), 1) self.assertEqual({'loc': 'Invalid GPS value.'}, errors) self.assertEqual(OrderedDict([('ID', '1')]), cleaned_answers) self.assertEqual(len(self.form_model.validation_exception), 1) self.assertTrue( isinstance(self.form_model.validation_exception[0], ex.LatitudeNotInRange)) def test_should_ignore_field_validation_if_the_answer_is_not_present(self): answers = {"id": "1", "q1": "Asif Momin", "q2": "20"} expected_result = OrderedDict([('Q1', 'Asif Momin'), ('Q2', 20.0), ('ID', '1')]) cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertTrue(len(errors) == 0) self.assertEqual(cleaned_answers, expected_result) def test_should_validate_for_valid_text_value(self): answers = {"ID": "1", "Q1": "Asif Momin"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertTrue(len(errors) == 0) def test_should_return_errors_for_invalid_text_and_integer(self): answers = {"id": "1", "Q1": "Asif", "Q2": "200", "q3": "a"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertEqual(len(errors), 2) self.assertEqual( { 'Q1': 'Answer Asif for question Q1 is shorter than allowed.', 'Q2': "Answer 200 for question Q2 is greater than allowed." }, errors) self.assertEqual(OrderedDict([('Q3', ['RED']), ('ID', '1')]), cleaned_answers) self.assertTrue( isinstance(self.form_model.validation_exception[1], ex.AnswerTooBigException)) self.assertTrue( isinstance(self.form_model.validation_exception[0], ex.AnswerTooShortException)) self.assertEqual(len(self.form_model.validation_exception), 2) def test_should_strip_whitespaces(self): answers = { "id": "1", "q1": " My Name", "q2": " 40 ", "q3": "a ", "q4": " " } expected_cleaned_data = OrderedDict([('Q1', 'My Name'), ('Q3', ['RED']), ('Q2', 40.0), ('ID', '1')]) cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertTrue(len(errors) == 0) self.assertEqual(0, len(errors)) self.assertEqual(cleaned_answers, expected_cleaned_data) def test_should_validate_field_case_insensitive(self): answers = {"Id": "1", "Q1": "Asif Momin", "q2": "40"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertTrue(len(errors) == 0) self.assertEqual({}, errors) def test_should_return_valid_form_submission(self): answers = {"ID": "1", "Q2": "16"} cleaned_data, errors = self.form_model.validate_submission(answers) self.assertEqual({"Q2": 16.0, 'ID': '1'}, cleaned_data) self.assertEqual(0, len(errors)) def test_should_return_invalid_form_submission(self): answers = {"ID": "1", "Q2": "non number value"} cleaned_data, errors = self.form_model.validate_submission(answers) self.assertEqual({'ID': '1'}, cleaned_data) self.assertEqual(1, len(errors)) self.assertEqual(1, len(self.form_model.validation_exception)) self.assertTrue( isinstance(self.form_model.validation_exception[0], ex.AnswerWrongType)) def test_should_give_back_unique_id_field(self): question1 = UniqueIdField('entity_type', name="question1_Name", code="Q1", label="What is your name", defaultValue="some default value") activity_report = FormModel(self.dbm, name="aids", label="Aids form_model", form_code="1", fields=[question1]) self.assertIsNotNone(activity_report.entity_questions) def _case_insensitive_lookup(self, values, code): for fieldcode in values: if fieldcode.lower() == code.lower(): return values[fieldcode] return None def test_should_bind_form_to_submission(self): answers = {"ID": "1", "q1": "Asif", "q2": "200", "q3": "1", "q4": ""} self.form_model.bind(answers) self.assertEqual(answers, self.form_model.submission) for field in self.form_model.fields: self.assertEqual( self._case_insensitive_lookup(answers, field.code), field.value, "No match for field %s" % (field.code, )) def test_should_set_error_on_field_validation_failure(self): answers = {"id": "1", "q1": "ab", "q2": "200"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertEqual(len(errors), 2) self.assertEqual( ["Answer 200 for question Q2 is greater than allowed."], self.form_model.get_field_by_code("q2").errors) self.assertEqual( ['Answer ab for question Q1 is shorter than allowed.'], self.form_model.get_field_by_code("q1").errors) def test_should_not_set_error_if_validation_success(self): answers = {"id": "1", "q1": "abcdef", "q2": "100"} cleaned_answers, errors = self.form_model.validate_submission(answers) self.assertEqual(len(errors), 0) for field in self.form_model.fields: self.assertEqual([], field.errors) self.assertEqual(self.form_model.validation_exception, []) def test_should_return_choice_fields(self): self.assertEquals(self.form_model.choice_fields[0].code, "Q3") self.assertEquals(len(self.form_model.choice_fields), 1) def test_should_return_dictionary_of_question_code_and_label(self): dictionary = self.form_model.get_field_code_label_dict() codes = dictionary.keys() values = dictionary.values() self.assertEquals(7, dictionary.__len__()) self.assertEquals(["ID", "Q1", "Q2", "Q3", "Q4", "Q6", "loc"].sort(), codes.sort()) self.assertEquals([ "What is associated entity", "What is your name", "What is your Father's Age", "What is your favourite color", "Description", "Event time field", "Geo Location Field" ].sort(), values.sort()) def test_should_add_validator_to_form_model_if_not_already_present(self): self.form_model.validators = [MandatoryValidator()] self.form_model.add_validator(UniqueIdExistsValidator) self.assertEquals(len(self.form_model.validators), 2) def test_should_not_add_validator_to_form_model_if_already_present(self): self.form_model.validators = [ MandatoryValidator(), UniqueIdExistsValidator() ] self.form_model.add_validator(UniqueIdExistsValidator) self.assertEquals(len(self.form_model.validators), 2) def test_should_remove_validator_from_form_model(self): self.form_model.validators = [ MandatoryValidator(), UniqueIdExistsValidator() ] self.form_model.remove_validator(UniqueIdExistsValidator) self.assertEquals(len(self.form_model.validators), 1) def test_should_get_entity_form_model_if_registration_flag_is_set(self): with patch('mangrove.form_model.form_model.get_cache_manager' ) as get_cache_manager: with patch( 'mangrove.form_model.form_model.get_form_model_cache_key' ) as get_form_model_cache_key: get_cache_manager.return_value = { 'cache_key': { 'is_registration_model': True } } get_form_model_cache_key.return_value = 'cache_key' form_model = get_form_model_by_code(self.dbm, 'code') self.assertIsInstance(form_model, EntityFormModel) def test_should_get_submission_form_model_if_registration_flag_is_false( self): with patch('mangrove.form_model.form_model.get_cache_manager' ) as get_cache_manager: with patch( 'mangrove.form_model.form_model.get_form_model_cache_key' ) as get_form_model_cache_key: get_cache_manager.return_value = { 'cache_key': { 'is_registration_model': False } } get_form_model_cache_key.return_value = 'cache_key' form_model = get_form_model_by_code(self.dbm, 'code') self.assertIsInstance(form_model, FormModel) def test_should_return_entity_form_model_based_on_entity_type(self): dbm = DatabaseManagerStub() dbm.view.registration_form_model_by_entity_type.return_value = [{ 'doc': { 'is_registration_form': True } }] form_model = get_form_model_by_entity_type(dbm, ['entity_type']) self.assertIsInstance(form_model, EntityFormModel) self.assertTrue(hasattr(form_model, 'entity_type')) def test_should_filter_duplicate_unique_id_types(self): field1 = UniqueIdField(unique_id_type='clinic', name='q1', code='q1', label='q1') field2 = UniqueIdField(unique_id_type='school', name='q2', code='q2', label='q2') field3 = UniqueIdField(unique_id_type='clinic', name='q3', code='q3', label='q3') fields = [field1, field2, field3] form_model = FormModel(Mock(spec=DatabaseManager)) form_model._form_fields = fields self.assertListEqual(['clinic', 'school'], form_model.entity_type) def test_should_get_field_from_field_set(self): field1 = TextField('text', 'text', 'text label', parent_field_code='field_set_code') field2 = TextField('text1', 'text1', 'text label1', parent_field_code='field_set_code') fieldset_field = FieldSet('field_set', 'field_set_code', 'field set label', field_set=[field1, field2]) form_model = FormModel(Mock(spec=DatabaseManager)) form_model._form_fields = [fieldset_field] self.assertEqual( field1, form_model.get_field_by_code_in_fieldset('text', 'field_set_code'))