def test_invalidate_entity(self):
     e = Entity(self.dbm, entity_type='store', location=['nyc'])
     e.save()
     self.assertFalse(e._doc.void)
     apple_type = DataDictType(self.dbm,
                               name='Apples',
                               slug='apples',
                               primitive_type='number')
     orange_type = DataDictType(self.dbm,
                                name='Oranges',
                                slug='oranges',
                                primitive_type='number')
     apple_type.save()
     orange_type.save()
     data = [[('apples', 20, apple_type), ('oranges', 30, orange_type)],
             [('apples', 10, apple_type), ('oranges', 20, orange_type)]]
     data_ids = []
     for d in data:
         id = e.add_data(d)
         self.assertFalse(self.dbm._load_document(id).void)
         data_ids.append(id)
     e.invalidate()
     self.assertTrue(e._doc.void)
     for id in data_ids:
         self.assertTrue(self.dbm._load_document(id).void)
 def test_invalidate_data(self):
     e = Entity(self.dbm, entity_type='store', location=['nyc'])
     e.save()
     apple_type = DataDictType(self.dbm, name='Apples', slug='apples', primitive_type='number')
     orange_type = DataDictType(self.dbm, name='Oranges', slug='oranges', primitive_type='number')
     apple_type.save()
     orange_type.save()
     data = e.add_data([('apples', 20, apple_type), ('oranges', 30, orange_type)])
     valid_doc = self.dbm._load_document(data)
     self.assertFalse(valid_doc.void)
     e.invalidate_data(data)
     invalid_doc = self.dbm._load_document(data)
     self.assertTrue(invalid_doc.void)
 def _create_data_dict_type(self):
     med_type = DataDictType(self.dbm,
                             name='Medicines',
                             slug='meds',
                             primitive_type='number',
                             description='Number of medications')
     doctor_type = DataDictType(self.dbm,
                                name='Doctor',
                                slug='doc',
                                primitive_type='string',
                                description='Name of doctor')
     facility_type = DataDictType(self.dbm,
                                  name='Facility',
                                  slug='facility',
                                  primitive_type='string',
                                  description='Name of facility')
     opened_type = DataDictType(self.dbm,
                                name='Opened on',
                                slug='opened_on',
                                primitive_type='datetime',
                                description='Date of opening')
     med_type.save()
     doctor_type.save()
     facility_type.save()
     opened_type.save()
     return doctor_type, facility_type, med_type, opened_type
 def test_invalidate_data(self):
     e = Entity(self.dbm, entity_type='store', location=['nyc'])
     e.save()
     apple_type = DataDictType(self.dbm,
                               name='Apples',
                               slug='apples',
                               primitive_type='number')
     orange_type = DataDictType(self.dbm,
                                name='Oranges',
                                slug='oranges',
                                primitive_type='number')
     apple_type.save()
     orange_type.save()
     data = e.add_data([('apples', 20, apple_type),
                        ('oranges', 30, orange_type)])
     valid_doc = self.dbm._load_document(data)
     self.assertFalse(valid_doc.void)
     e.invalidate_data(data)
     invalid_doc = self.dbm._load_document(data)
     self.assertTrue(invalid_doc.void)
 def test_invalidate_entity(self):
     e = Entity(self.dbm, entity_type='store', location=['nyc'])
     e.save()
     self.assertFalse(e._doc.void)
     apple_type = DataDictType(self.dbm, name='Apples', slug='apples', primitive_type='number')
     orange_type = DataDictType(self.dbm, name='Oranges', slug='oranges', primitive_type='number')
     apple_type.save()
     orange_type.save()
     data = [
         [('apples', 20, apple_type), ('oranges', 30, orange_type)],
         [('apples', 10, apple_type), ('oranges', 20, orange_type)]
     ]
     data_ids = []
     for d in data:
         id = e.add_data(d)
         self.assertFalse(self.dbm._load_document(id).void)
         data_ids.append(id)
     e.invalidate()
     self.assertTrue(e._doc.void)
     for id in data_ids:
         self.assertTrue(self.dbm._load_document(id).void)
 def _create_data_dict_type(self):
     med_type = DataDictType(self.dbm, name='Medicines', slug='meds', primitive_type='number',
                             description='Number of medications')
     doctor_type = DataDictType(self.dbm, name='Doctor', slug='doc', primitive_type='string',
                                description='Name of doctor')
     facility_type = DataDictType(self.dbm, name='Facility', slug='facility', primitive_type='string',
                                  description='Name of facility')
     opened_type = DataDictType(self.dbm, name='Opened on', slug='opened_on', primitive_type='datetime',
                                description='Date of opening')
     med_type.save()
     doctor_type.save()
     facility_type.save()
     opened_type.save()
     return doctor_type, facility_type, med_type, opened_type
 def test_should_return_data_types(self):
     med_type = DataDictType(self.dbm,
                             name='Medicines',
                             slug='meds',
                             primitive_type='number',
                             description='Number of medications',
                             tags=['med'])
     med_type.save()
     doctor_type = DataDictType(self.dbm,
                                name='Doctor',
                                slug='doc',
                                primitive_type='string',
                                description='Name of doctor',
                                tags=['doctor', 'med'])
     doctor_type.save()
     facility_type = DataDictType(self.dbm,
                                  name='Facility',
                                  slug='facility',
                                  primitive_type='string',
                                  description='Name of facility')
     facility_type.save()
     e = Entity(self.dbm, entity_type='foo')
     e.save()
     data_record = [('meds', 20, med_type),
             ('doc', "aroj", doctor_type),
             ('facility', 'clinic', facility_type)]
     e.add_data(data_record)
     # med (tag in list)
     types = [typ.slug for typ in e.data_types(['med'])]
     self.assertTrue(med_type.slug in types)
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(facility_type.slug not in types)
     # doctor (tag as string)
     types = [typ.slug for typ in e.data_types('doctor')]
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(med_type.slug not in types)
     self.assertTrue(facility_type.slug not in types)
     # med and doctor (more than one tag)
     types = [typ.slug for typ in e.data_types(['med', 'doctor'])]
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(med_type.slug not in types)
     self.assertTrue(facility_type.slug not in types)
     # no tags
     types = [typ.slug for typ in e.data_types()]
     self.assertTrue(med_type.slug in types)
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(facility_type.slug in types)
 def test_should_return_data_types(self):
     med_type = DataDictType(self.dbm,
                             name='Medicines',
                             slug='meds',
                             primitive_type='number',
                             description='Number of medications',
                             tags=['med'])
     med_type.save()
     doctor_type = DataDictType(self.dbm,
                                name='Doctor',
                                slug='doc',
                                primitive_type='string',
                                description='Name of doctor',
                                tags=['doctor', 'med'])
     doctor_type.save()
     facility_type = DataDictType(self.dbm,
                                  name='Facility',
                                  slug='facility',
                                  primitive_type='string',
                                  description='Name of facility')
     facility_type.save()
     e = Entity(self.dbm, entity_type='foo')
     e.save()
     data_record = [('meds', 20, med_type), ('doc', "aroj", doctor_type),
                    ('facility', 'clinic', facility_type)]
     e.add_data(data_record)
     # med (tag in list)
     types = [typ.slug for typ in e.data_types(['med'])]
     self.assertTrue(med_type.slug in types)
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(facility_type.slug not in types)
     # doctor (tag as string)
     types = [typ.slug for typ in e.data_types('doctor')]
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(med_type.slug not in types)
     self.assertTrue(facility_type.slug not in types)
     # med and doctor (more than one tag)
     types = [typ.slug for typ in e.data_types(['med', 'doctor'])]
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(med_type.slug not in types)
     self.assertTrue(facility_type.slug not in types)
     # no tags
     types = [typ.slug for typ in e.data_types()]
     self.assertTrue(med_type.slug in types)
     self.assertTrue(doctor_type.slug in types)
     self.assertTrue(facility_type.slug in types)
Exemple #9
0
class TestQuestionnaireBuilder(MangroveTestCase):
    def setUp(self):
        MangroveTestCase.setUp(self)
        self._create_default_dd_type()

    def tearDown(self):
        MangroveTestCase.tearDown(self)

    def test_should_update_questionnaire_when_entity_type_is_not_reporter(
            self):
        self._create_form_model()
        form_model = self.manager.get(self.form_model__id, FormModel)
        post = [{
            "title": "What is your age",
            "code": "age",
            "type": "integer",
            "choices": [],
            "is_entity_question": False,
            "range_min": 0,
            "range_max": 100
        }]

        QuestionnaireBuilder(
            form_model, self.manager).update_questionnaire_with_questions(post)
        self.assertEquals(1, len(form_model.fields))

    def test_should_update_questionnaire_when_entity_type_is_reporter(self):
        self._create_summary_form_model()
        post = [{
            "title": "q1",
            "type": "text",
            "choices": [],
            "is_entity_question": False,
            "code": "q1",
            "min_length": 1,
            "max_length": ""
        }, {
            "title": "q2",
            "type": "integer",
            "choices": [],
            "is_entity_question": False,
            "code": "code",
            "range_min": 0,
            "range_max": 100
        }, {
            "title": "q3",
            "type": "select",
            "code": "code",
            "choices": [{
                "value": "c1"
            }, {
                "value": "c2"
            }],
            "is_entity_question": False
        }]
        summary_form_model = self.manager.get(self.summary_form_model__id,
                                              FormModel)
        QuestionnaireBuilder(
            summary_form_model,
            self.manager).update_questionnaire_with_questions(post)
        self.assertEqual(4, len(summary_form_model.fields))
        self.assertEqual('eid', summary_form_model.fields[0].code)
        self.assertEqual('q1', summary_form_model.fields[1].code)
        self.assertEqual('q2', summary_form_model.fields[2].code)
        self.assertEqual('q3', summary_form_model.fields[3].code)
        entity_id_question = summary_form_model.entity_question
        self.assertEqual('eid', entity_id_question.code)
        self.assertEqual('I am submitting this data on behalf of',
                         entity_id_question.name)
        self.assertEqual("Choose Data Sender from this list.",
                         entity_id_question.instruction)

    def test_should_no_snapshot_when_questionnaire_first_created(self):
        self._create_form_model()
        form_model = self.manager.get(self.form_model__id, FormModel)
        self.assertEqual(0, len(form_model.snapshots))

    def test_should_save_snapshots_when_questionnaires_field_modified(self):
        self._create_form_model()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)
        original_fields = form_model._doc.json_fields
        revision = form_model._doc['_rev']

        post = [{
            "title": "q1",
            "type": "text",
            "choices": [],
            "is_entity_question": False,
            "code": "q1",
            "min_length": 1,
            "max_length": ""
        }, {
            "title": "q2",
            "type": "integer",
            "choices": [],
            "is_entity_question": False,
            "code": "q2",
            "range_min": 0,
            "range_max": 100
        }]
        QuestionnaireBuilder(
            form_model, self.manager).update_questionnaire_with_questions(post)
        form_model.save()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)

        self.assertEqual(1, len(form_model.snapshots))
        self.assertEqual(revision, form_model.snapshots.keys()[-1])
        expect = [(each['code'], each['label']) for each in original_fields]
        self.assertListEqual(expect,
                             [(each.code, each.label)
                              for each in form_model.snapshots[revision]])

    @SkipTest  # ddtype comparison not solved
    def test_should_not_save_snapshots_when_questionnaires_field_not_changed(
            self):
        self._create_form_model()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)

        post = [{
            "title": "What is associated entity",
            "options": {
                "ddtype": self.default_ddtype.to_json()
            },
            "type": "text",
            "is_entity_question": True,
            "code": "ID",
            "name": "entity_question"
        }, {
            "title": "What is your name",
            "options": {
                "ddtype": self.default_ddtype.to_json()
            },
            "type": "text",
            "is_entity_question": False,
            "code": "Q1",
            "range_min": 5,
            "range_max": 10
        }]
        QuestionnaireBuilder(
            form_model, self.manager).update_questionnaire_with_questions(post)
        form_model.save()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)

        self.assertEqual(0, len(form_model.snapshots))

    def _create_form_model(self):
        question1 = TextField(name="entity_question",
                              code="ID",
                              label="What is associated entity",
                              entity_question_flag=True,
                              ddtype=self.default_ddtype)
        question2 = TextField(
            name="question1_Name",
            code="Q1",
            label="What is your name",
            defaultValue="some default value",
            constraints=[TextLengthConstraint(5, 10),
                         RegexConstraint("\w+")],
            ddtype=self.default_ddtype)
        self.form_model = FormModel(self.manager,
                                    entity_type=self.entity_type,
                                    name="aids",
                                    label="Aids form_model",
                                    form_code=FORM_CODE_1,
                                    type='survey',
                                    fields=[question1, question2])
        self.form_model__id = self.form_model.save()

    def _create_summary_form_model(self):
        question1 = TextField(
            name="question1_Name",
            code="Q1",
            label="What is your name",
            defaultValue="some default value",
            constraints=[TextLengthConstraint(5, 10),
                         RegexConstraint("\w+")],
            ddtype=self.default_ddtype)
        question2 = IntegerField(
            name="Father's age",
            code="Q2",
            label="What is your Father's Age",
            constraints=[NumericRangeConstraint(min=15, max=120)],
            ddtype=self.default_ddtype)
        question3 = SelectField(name="Color",
                                code="Q3",
                                label="What is your favourite color",
                                options=[("RED", 1), ("YELLOW", 2)],
                                ddtype=self.default_ddtype)
        self.summary_form_model = FormModel(
            self.manager,
            entity_type=["reporter"],
            name="aids",
            label="Aids form_model",
            form_code=FORM_CODE_2,
            type="survey",
            fields=[question1, question2, question3])
        self.summary_form_model__id = self.summary_form_model.save()

    def _create_default_dd_type(self):
        self.entity_type = ["HealthFacility", "Clinic"]
        define_type(self.manager, ["HealthFacility", "Clinic"])
        self.default_ddtype = DataDictType(self.manager,
                                           name='Default String Datadict Type',
                                           slug='string_default',
                                           primitive_type='string')
        self.default_ddtype.save()
class TestFormModel(unittest.TestCase):
    def setUp(self):
        self.dbm = get_db_manager(database='mangrove-test')
        self._create_form_model()

    def tearDown(self):
        _delete_db_and_remove_db_manager(self.dbm)

    def test_create_form_model(self):
        self.assertTrue(self.form_model__id)

    def test_should_create_registration_form_model(self):
        form = create_default_reg_form_model(self.dbm)
        self.assertEqual(7, len(form.fields))
        self.assertEqual(REGISTRATION_FORM_CODE, form.form_code)
        self.assertEqual('string', form.fields[3].ddtype.primitive_type)

    def test_get_form_model(self):
        e = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(e.id)
        self.assertTrue(e.type == "survey")


    def test_should_add_name_of_form_model(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(saved.name == "aids")


    def test_should_add_label(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(saved.label['eng'] == "Aids form_model")

    def test_should_add_short_ids(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(saved.form_code == "1")

    def test_should_add_entity_id(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertListEqual(saved.entity_type, self.entity_type)

    def test_should_add_fields(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(len(saved.fields) == 4)
        self.assertTrue(saved.fields[1].name == "question1_Name")
        self.assertTrue(saved.fields[2].name == "Father's age")

    def test_should_add_integer_field_with_constraints(self):
        integer_question = self.dbm.get(self.form_model__id, FormModel).fields[2]
        range_constraint = integer_question.range
        self.assertTrue(integer_question.name == "Father's age")
        self.assertTrue(range_constraint.get("min"), 15)
        self.assertTrue(range_constraint.get("max"), 120)

    def test_should_add_select1_field(self):
        select_question = self.dbm.get(self.form_model__id, FormModel).fields[3]
        option_constraint = select_question.options

        self.assertEquals(len(option_constraint), 2)
        self.assertEquals(option_constraint[0].get("val"), 1)

    def test_should_add_new_field(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        question = TextField(name="added_question", code="Q4", label="How are you", ddtype=self.default_ddtype)
        form_model.add_field(question)
        form_model.save()

        added_question = self.dbm.get(self.form_model__id, FormModel).fields[4]
        self.assertEquals(added_question.code, "Q4")

    def test_should_delete_field(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.delete_field(code="Q3")
        form_model.save()
        form_model = self.dbm.get(self.form_model__id, FormModel)
        self.assertEquals(len(form_model.fields), 3)

    def test_should_add_english_as_default_langauge(self):
        activeLangauges = self.form_model.activeLanguages
        self.assertTrue("eng" in activeLangauges)

    def test_should_add_language_to_form_model(self):
        self.form_model.add_language(language="fra", label="French Aids form_model")
        activeLangauges = self.form_model.activeLanguages
        self.assertEquals(len(activeLangauges), 2)
        self.assertTrue("fra" in activeLangauges)
        self.assertEquals(self.form_model.label['fra'], u'French Aids form_model')

    def test_should_delete_all_fields_from_document(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.delete_all_fields()
        self.assertEquals(len(form_model.fields), 0)

    def test_should_delete_all_fields_from_questions(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.delete_all_fields()
        self.assertEquals(len(form_model.fields), 0)

    def test_should_raise_exception_if_entity_field_already_exist(self):
        with self.assertRaises(EntityQuestionAlreadyExistsException):
            form_model = self.dbm.get(self.form_model__id, FormModel)
            question = TextField(name="added_question", code="Q5", label="How are you",
                                 entity_question_flag=True, ddtype=self.default_ddtype)
            form_model.add_field(question)
            form_model.save()

    def test_should_raise_exception_if_code_is_not_unique(self):
        with self.assertRaises(QuestionCodeAlreadyExistsException):
            form_model = self.dbm.get(self.form_model__id, FormModel)
            question = TextField(name="added_question", code="q1", label="How are you",
                                 ddtype=self.default_ddtype)
            form_model.add_field(question)
            form_model.save()

    def test_should_set_form_code(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.form_code = "xyz"
        self.assertEquals(form_model.form_code, "xyz")

    def test_should_persist_ddtype(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)

        self.assertEqual(form_model.fields[0].ddtype.slug, self.default_ddtype.slug)
        self.assertEqual(form_model.fields[0].ddtype.id, self.default_ddtype.id)
        self.assertEqual(form_model.fields[0].ddtype.name, self.default_ddtype.name)

        self.assertEqual(form_model.fields[1].ddtype.slug, self.default_ddtype.slug)
        self.assertEqual(form_model.fields[1].ddtype.id, self.default_ddtype.id)
        self.assertEqual(form_model.fields[1].ddtype.name, self.default_ddtype.name)

        self.assertEqual(form_model.fields[2].ddtype.slug, self.default_ddtype.slug)
        self.assertEqual(form_model.fields[2].ddtype.id, self.default_ddtype.id)
        self.assertEqual(form_model.fields[2].ddtype.name, self.default_ddtype.name)

        self.assertEqual(form_model.fields[3].ddtype.slug, self.default_ddtype.slug)
        self.assertEqual(form_model.fields[3].ddtype.id, self.default_ddtype.id)
        self.assertEqual(form_model.fields[3].ddtype.name, self.default_ddtype.name)

    def test_should_set_entity_type(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.entity_id = "xyz"
        self.assertEquals(form_model.entity_id, "xyz")


    def test_should_create_a_questionnaire_from_dictionary(self):
        fields = [
                {
                "name": "What are you reporting on?",
                "defaultValue": "",
                "label": {
                    "eng": "Entity being reported on"
                },
                "entity_question_flag": True,
                "type": "text",
                "ddtype": self.default_ddtype.to_json(),
                "code": "eid",
                "length": {"min": 1, "max": 10},
                },
                {
                "range": {
                    "max": 10,
                    "min": 0
                },
                "label": {"eng": ""},
                "type": "integer",
                "ddtype": self.default_ddtype.to_json(),
                "name": "What is your age?",
                "code": "AGE"
            },
                {
                "choices": [
                        {
                        "text": {"eng": "Pune"}
                    },
                        {
                        "text": {"eng": "Bangalore"}
                    }
                ],
                "label": {"eng": ""},
                "type": "select",
                "ddtype": self.default_ddtype.to_json(),
                "name": "Where do you live?",
                "code": "PLC"
            }]
        document = FormModelDocument()
        document.json_fields = fields
        document.entity_type = ["Reporter"]
        document.document_type = "FormModel"
        document.form_code = "F1"
        document.name = "New Project"
        document.type = "survey"
        document.type = "survey"
        entityQ = TextField(name="What are you reporting on?", code="eid",
                            label="Entity being reported on", entity_question_flag=True,
                            length=TextConstraint(min=1, max=10), ddtype=self.default_ddtype)
        ageQ = IntegerField(name="What is your age?", code="AGE", label="",
                            range=NumericConstraint(min=0, max=10), ddtype=self.default_ddtype)
        placeQ = SelectField(name="Where do you live?", code="PLC", label="",
                             options=[{"text": {"eng": "Pune"}}, {"text": {"eng": "Bangalore"}}],
                             single_select_flag=False, ddtype=self.default_ddtype)
        questions = [entityQ, ageQ, placeQ]
        questionnaire = FormModel.new_from_doc(self.dbm, document)
        self.maxDiff = None
        self.assertListEqual(questionnaire.entity_type, ["Reporter"])
        self.assertEqual(questionnaire.name, "New Project")
        self.assertEqual(questionnaire.type, "survey")
        for i in range(len(questions)):
            self.assertEqual(questionnaire.fields[i]._to_json(), questions[i]._to_json())

    def test_should_set_name(self):
        self.form_model.name = 'test_name'
        self.assertEquals(self.form_model.name, 'test_name')


    def test_should_set_entity_type_in_doc(self):
        self.form_model.entity_type = ["WaterPoint", "Dam"]
        self.assertEqual(self.form_model.entity_type, ["WaterPoint", "Dam"])

    def test_should_raise_exception_if_form_code_already_exists_on_creation(self):
        question1 = TextField(name="entity_question", code="ID", label="What is associated entity",
                              language="eng", entity_question_flag=True, ddtype=self.default_ddtype)
        form_model = FormModel(self.dbm, entity_type=self.entity_type, name="aids", label="Aids form_model",
                               form_code="1", type='survey', fields=[question1])
        with self.assertRaises(DataObjectAlreadyExists):
            form_model.save()


    def test_should_raise_exception_if_form_code_already_exists_on_updation(self):
        question1 = TextField(name="entity_question", code="ID", label="What is associated entity",
                              language="eng", entity_question_flag=True, ddtype=self.default_ddtype)
        form_model2 = FormModel(self.dbm, entity_type=self.entity_type, name="aids", label="Aids form_model",
                                form_code="2", type='survey', fields=[question1])
        form_model2.save()
        with self.assertRaises(DataObjectAlreadyExists):
            form_model2.form_code = "1"

    def test_should_not_raise_exception_if_form_code_is_updated(self):
        question1 = TextField(name="entity_question", code="ID", label="What is associated entity",
                              language="eng", entity_question_flag=True, ddtype=self.default_ddtype)
        form_model2 = FormModel(self.dbm, entity_type=self.entity_type, name="aids", label="Aids form_model",
                                form_code="2", type='survey', fields=[question1])
        form_model2.save()
        form_model2.form_code = "2"
        form_model2.save()

    def test_to_html(self):
        expected_html ="""<input id=id_entity_question name=entity_question class=class_entity_question type="text"/><input id=id_question1_Name name=question1_Name class=class_question1_Name type="text"/><input id=id_Father's age name=Father's age class=class_Father's age type="text"/><select name="Color" ><option value="1">RED</option><option value="2">YELLOW</option></select>"""
        self.assertEqual(expected_html, to_html(self.form_model))

    def _create_form_model(self):
        self.entity_type = ["HealthFacility", "Clinic"]
        define_type(self.dbm, ["HealthFacility", "Clinic"])
        self.default_ddtype = DataDictType(self.dbm, name='Default String Datadict Type', slug='string_default',
                                           primitive_type='string')
        self.default_ddtype.save()
        question1 = TextField(name="entity_question", code="ID", label="What is associated entity",
                              language="eng", entity_question_flag=True, ddtype=self.default_ddtype)
        question2 = TextField(name="question1_Name", code="Q1", label="What is your name",
                              defaultValue="some default value", language="eng", length=TextConstraint(5, 10),
                              ddtype=self.default_ddtype)
        question3 = IntegerField(name="Father's age", code="Q2", label="What is your Father's Age",
                                 range=NumericConstraint(min=15, max=120), ddtype=self.default_ddtype)
        question4 = SelectField(name="Color", code="Q3", label="What is your favourite color",
                                options=[("RED", 1), ("YELLOW", 2)], ddtype=self.default_ddtype)
        self.form_model = FormModel(self.dbm, entity_type=self.entity_type, name="aids", label="Aids form_model",
                                    form_code="1", type='survey', fields=[
                question1, question2, question3, question4])
        self.form_model__id = self.form_model.save()
Exemple #11
0
class TestFilePlayer(MangroveTestCase):

    def setUp(self):
        MangroveTestCase.setUp(self)
        initializer.run(self.manager)

        self.entity_type = ["reporter"]
        self.telephone_number_type = DataDictType(self.manager, name='telephone_number', slug='telephone_number',
                                                  primitive_type='string')
        self.entity_id_type = DataDictType(self.manager, name='Entity Id Type', slug='entity_id', primitive_type='string')
        self.name_type = DataDictType(self.manager, name='Name', slug='name', primitive_type='string')
        self.telephone_number_type.save()
        self.name_type.save()
        self.reporter = create_entity(self.manager, entity_type=self.entity_type,
                                      location=["India", "Pune"], aggregation_paths=None, short_code="rep1",
                                      )
        self.reporter.add_data(data=[(MOBILE_NUMBER_FIELD, '1234', self.telephone_number_type),
            (NAME_FIELD, "Test_reporter", self.name_type)], submission=dict(submission_id="1"))

        question1 = TextField(name="entity_question", code="EID", label="What is associated entity",
                              entity_question_flag=True, ddtype=self.entity_id_type)
        question2 = TextField(name="Name", code="NAME", label="Clinic Name",
                              defaultValue="some default value",
                              ddtype=self.name_type, required=False)
        self.form_model = FormModel(self.manager, entity_type=self.entity_type, name="Dengue", label="Dengue form_model",
                                    form_code="clinic", type='survey', fields=[question1,question2])
        self.form_model.save()

        self.csv_data_for_activity_report = """
                                FORM_CODE,EID,NAME
                                clinic,rep1,XYZ
        """
        self.csv_data_about_reporter = """
                                FORM_CODE,t,n,l,d,m
                                REG,"reporter",Dr. A,Pune,"Description",201
        """
        self.csv_data_with_same_mobile_number = """
                                FORM_CODE,t,n,l,d,m
                                REG,"reporter",Dr. A,Pune,"Description",201
                                REG,"reporter",Dr. B,Pune,"Description",201
        """
        self.csv_data_with_exception = """
                                FORM_CODE,t,n,l,d,m
                                REG,"reporter",Dr. A,Pune,"Description",201
                                REG,"reporter",Dr. B,Pune,"Description",201
                                REG,"reporter",Dr. C,Pune,"Description",202
        """
        self.csv_data_with_missing_name = """
                                FORM_CODE,t,n,l,d,m
                                REG,"reporter",,Pune,"Description",201
        """
        self.csv_data_with_missing_type = """
                                FORM_CODE,t,n,l,d,m
                                REG,,Dr. A,Pune,"Description",201
        """
        self.csv_data_with_incorrect_mobile_number = """
                                FORM_CODE,t,n,l,d,m
                                REG,"reporter",Dr. A,Pune,"Description",2014678447676512
                                REG,"reporter",Dr. A,Pune,"Description",~!@#$%^&*()+|}
                                REG,"reporter",Dr. A,Pune,"Description",
        """
        self.csv_data_with_incorrect_GPS = """
                                FORM_CODE,t,n,g,d,m
                                REG,"reporter",Dr. A,18,"Description",201
        """
        self.csv_data_with_out_of_range_GPS_value = """
                                FORM_CODE,t,n,g,d,m
                                REG,"reporter",Dr. A,-95 48,"Description",201
                                REG,"reporter",Dr. A,-18 184,"Description",201
        """
        self.csv_data_without_form_code= """
                                FORM_CODE,t,n,g,d,m
                                ,"reporter",Dr. A,-95 48,"Description",201
                                ABC,"reporter",Dr. A,-95 48,"Description",201
        """
        self.parser = CsvParser()
        self.file_player = FilePlayer(self.manager,self.parser, Channel.CSV, LocationBridge(DummyLocationTree(),dummy_get_location_hierarchy))

    def tearDown(self):
        MangroveTestCase.tearDown(self)

    def test_should_import_csv_string_if_it_contains_data_about_reporters(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_about_reporter)
        self.assertTrue(responses[0].success)
        submission_log = Submission.get(self.manager, responses[0].submission_id)
        self.assertEquals(True, submission_log. status)
        self.assertEquals("csv", submission_log.channel)
        self.assertEquals("reg", submission_log.form_code)
        self.assertDictContainsSubset({'t':'reporter', 'n':'Dr. A','l':'Pune','d':'Description','m':'201'}, submission_log.values)

    def test_should_import_csv_string_if_it_contains_data_for_activity_reporters(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_for_activity_report)
        self.assertTrue(responses[0].success)
        submission_log = Submission.get(self.manager, responses[0].submission_id)
        self.assertEquals("csv", submission_log.channel)
        self.assertEquals(u'rep1', responses[0].short_code)

    def test_should_not_import_data_if_multiple_reporter_have_same_mobile_number(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_with_same_mobile_number)
        self.assertTrue(responses[0].success)
        self.assertFalse(responses[1].success)
        self.assertEqual(u'Sorry, the telephone number 201 has already been registered',responses[1].errors['error']['m'])

    def test_should_import_next_value_if_exception_with_previous(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_with_exception)
        self.assertTrue(responses[0].success)
        self.assertFalse(responses[1].success)
        self.assertTrue(responses[2].success)
        submission_log = Submission.get(self.manager, responses[0].submission_id)
        self.assertDictContainsSubset({'t':'reporter', 'n':'Dr. A','l':'Pune','d':'Description','m':'201'}, submission_log.values)
        self.assertEquals({'error':{'m': u'Sorry, the telephone number 201 has already been registered'}, 'row':{'t':u'reporter', 'n':u'Dr. B','l':[u'arantany'],'d':u'Description','m':u'201','s':u'rep3'}}, responses[1].errors)
        submission_log = Submission.get(self.manager, responses[2].submission_id)
        self.assertDictContainsSubset({'t':'reporter', 'n':'Dr. C','l':'Pune','d':'Description','m':'202'}, submission_log.values)

    def test_should_not_import_data_for_missing_field(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_with_missing_name)
            self.assertFalse(responses[0].success)
            self.assertEqual(OrderedDict([('n', 'Answer for question n is required')]),responses[0].errors['error'])

            responses = self.file_player.accept(self.csv_data_with_missing_type)
            self.assertFalse(responses[0].success)
            self.assertEqual(OrderedDict([('t', 'Answer for question t is required')]),responses[0].errors['error'])

    def test_should_not_import_data_for_invalid_mobile_number(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_with_incorrect_mobile_number)
        self.assertFalse(responses[0].success)
        self.assertFalse(responses[1].success)
        self.assertFalse(responses[2].success)
        self.assertEqual(OrderedDict([('m', 'Answer 2014678447676512 for question m is longer than allowed.')]),responses[0].errors['error'])
        self.assertEqual(OrderedDict([('m', 'Invalid Mobile Number. Only Numbers and Dash(-) allowed.')]),responses[1].errors['error'])
        self.assertEqual(OrderedDict([('m', 'Mobile number is missing')]),responses[2].errors['error'])

    def test_should_not_import_data_for_incorrect_GPS_format(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_with_incorrect_GPS)
        self.assertFalse(responses[0].success)
        error_message = OrderedDict([('g',
            'Incorrect GPS format. The GPS coordinates must be in the following format: xx.xxxx yy.yyyy. Example -18.8665 47.5315')])
        self.assertEqual(error_message,responses[0].errors['error'])

    def test_should_not_import_data_for_out_of_range_GPS_code(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_with_out_of_range_GPS_value)
        self.assertFalse(responses[0].success)
        self.assertFalse(responses[1].success)
        error_message1 = OrderedDict([('g',
            'The answer -95 must be between -90 and 90')])
        self.assertEqual(error_message1,responses[0].errors['error'])
        error_message2 = OrderedDict([('g',
            'The answer 184 must be between -180 and 180')])
        self.assertEqual(error_message2,responses[1].errors['error'])

    def test_should_not_import_data_for_invalid_form_code(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(self.csv_data_without_form_code)
        self.assertFalse(responses[0].success)
        self.assertEqual('The questionnaire does not exist.',responses[0].errors['error'])
        self.assertFalse(responses[1].success)
        self.assertEqual(u'The questionnaire with code abc does not exist.',responses[1].errors['error'])

    def test_should_not_import_ds_if_phone_number_already_registered(self):
        organization = Mock(spec=Organization)
        csv_data = """
                                FORM_CODE,t,n,l,d,m
                                REG,"reporter",used number,Tana,"...",1234567890
        """
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            responses = self.file_player.accept(csv_data)
                
        self.assertFalse(responses[0].success)
        self.assertEqual(responses[0].errors['error'],"Data Sender with Mobile Number = 1234567890 already exists.")

    def test_should_not_import_datasender_when_email_is_not_unique_or_mobile_is_not_unique(self):
        organization = Mock(spec=Organization)
        with patch("datawinners.utils.get_organization_from_manager") as get_organization_from_dbm_mock:
            get_organization_from_dbm_mock.return_value = Mock(return_value=organization)
            with patch.object(XlsDatasenderParser, "parse") as parse_mock:
                parse_mock.return_value = [
                    ("reg", {u"email": u'', u'g': u'-18.13,27.65', u'l': u'Nairobi',u'm': u'1234567890', u'n': u'Thierry Rakoto', u't': 'reporter'}),
                    ("reg", {u"email": u'*****@*****.**', u'g': u'-18.13,27.65', u'l': u'Nairobi',u'm': u'033333333', u'n': u'Thierry Rakoto', u't': 'reporter'}),
                    ("reg", {u"email": u'a.com', u'g': u'-18.13,27.65', u'l': u'Nairobi',u'm': u'033333333', u'n': u'Thierry Rakoto', u't': 'reporter'})
                ]
                with patch.object(UserManager, "values_list") as get_ds_mobile:
                    get_ds_mobile.return_value = ["*****@*****.**"]
                    file_player = FilePlayer(self.manager,XlsDatasenderParser(), Channel.XLS, LocationBridge(DummyLocationTree(),dummy_get_location_hierarchy))
                    responses = file_player.accept(None)
        self.assertFalse(responses[0].success)
        self.assertEqual(responses[0].errors['error'],"Data Sender with Mobile Number = 1234567890 already exists.")
        self.assertFalse(responses[1].success)
        self.assertEqual(responses[1].errors['error'],"User with email address = [email protected] already exists.")
        self.assertFalse(responses[2].success)
        self.assertEqual(responses[2].errors['error'],"Invalid email address.")

    def test_should_get_field_infos_of_registration_questionnaire(self):
        registration_form_model = self.manager.load_all_rows_in_view("questionnaire", key="reg")[0].get('value')
        fields, labels, codes = get_json_field_infos(registration_form_model.get('json_fields'))

        self.assertEqual(['name', 'short_code', 'location', 'geo_code', 'mobile_number'], fields)
        self.assertEqual(["What is the subject's name?", "What is the subject's Unique ID Number", "What is the subject's location?","What is the subject's GPS co-ordinates?", 'What is the mobile number associated with the subject?'], labels)
        self.assertEqual(['n', 's', 'l', 'g', 'm'], codes)

    def test_should_get_entity_type_info_for_reporter(self):
        info = get_entity_type_info('reporter', self.manager)
        expect = {'code': 'reg',
                  'codes': ['n', 's', 'l', 'g', 'm'],
                  'names': ['name', 'short_code', 'location', 'geo_code', 'mobile_number'],
                  'labels': ["What is the subject's name?", "What is the subject's Unique ID Number",
                             "What is the subject's location?", "What is the subject's GPS co-ordinates?",
                             'What is the mobile number associated with the subject?'],
                  'data': [],
                  'entity': 'reporter'}

        self.assertEqual(expect, info)

    def test_should_get_entity_type_info_for_subject(self):
        self._create_subject_registration_form()
        info = get_entity_type_info('clinic', self.manager)
        expect = {'code': u'form_code', 'codes': ['EID', 'BG'],
                  'names': [u'What is associat\xe9d entity?', 'What is your blood group?'],
                  'labels': ['What is associated entity?', 'What is your blood group?'], 'data': [], 'entity': 'clinic'}

        self.assertEqual(expect, info)

    def _create_subject_registration_form(self):
        eid_field = TextField(label="What is associated entity?", code="EID", name="What is associatéd entity?",entity_question_flag=True, ddtype=self.entity_id_type)
        blood_type_field = TextField(label="What is your blood group?", code="BG", name="What is your blood group?", ddtype=self.entity_id_type)
        return FormModelBuilder(self.manager, ["clinic"]).is_registration_model(True).add_fields(eid_field, blood_type_field).build()
class TestFormModel(unittest.TestCase):
    def setUp(self):
        self.dbm = get_db_manager(database='mangrove-test')
        self._create_form_model()

    def tearDown(self):
        _delete_db_and_remove_db_manager(self.dbm)

    def test_create_form_model(self):
        self.assertTrue(self.form_model__id)

    def test_should_create_registration_form_model(self):
        form = create_default_reg_form_model(self.dbm)
        self.assertEqual(7, len(form.fields))
        self.assertEqual(REGISTRATION_FORM_CODE, form.form_code)
        self.assertEqual('string', form.fields[3].ddtype.primitive_type)

    def test_get_form_model(self):
        e = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(e.id)
        self.assertTrue(e.type == "survey")

    def test_should_add_name_of_form_model(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(saved.name == "aids")

    def test_should_add_label(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(saved.label['eng'] == "Aids form_model")

    def test_should_add_short_ids(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(saved.form_code == "1")

    def test_should_add_entity_id(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertListEqual(saved.entity_type, self.entity_type)

    def test_should_add_fields(self):
        saved = self.dbm.get(self.form_model__id, FormModel)
        self.assertTrue(len(saved.fields) == 4)
        self.assertTrue(saved.fields[1].name == "question1_Name")
        self.assertTrue(saved.fields[2].name == "Father's age")

    def test_should_add_integer_field_with_constraints(self):
        integer_question = self.dbm.get(self.form_model__id,
                                        FormModel).fields[2]
        range_constraint = integer_question.range
        self.assertTrue(integer_question.name == "Father's age")
        self.assertTrue(range_constraint.get("min"), 15)
        self.assertTrue(range_constraint.get("max"), 120)

    def test_should_add_select1_field(self):
        select_question = self.dbm.get(self.form_model__id,
                                       FormModel).fields[3]
        option_constraint = select_question.options

        self.assertEquals(len(option_constraint), 2)
        self.assertEquals(option_constraint[0].get("val"), 1)

    def test_should_add_new_field(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        question = TextField(name="added_question",
                             code="Q4",
                             label="How are you",
                             ddtype=self.default_ddtype)
        form_model.add_field(question)
        form_model.save()

        added_question = self.dbm.get(self.form_model__id, FormModel).fields[4]
        self.assertEquals(added_question.code, "Q4")

    def test_should_delete_field(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.delete_field(code="Q3")
        form_model.save()
        form_model = self.dbm.get(self.form_model__id, FormModel)
        self.assertEquals(len(form_model.fields), 3)

    def test_should_add_english_as_default_langauge(self):
        activeLangauges = self.form_model.activeLanguages
        self.assertTrue("eng" in activeLangauges)

    def test_should_add_language_to_form_model(self):
        self.form_model.add_language(language="fra",
                                     label="French Aids form_model")
        activeLangauges = self.form_model.activeLanguages
        self.assertEquals(len(activeLangauges), 2)
        self.assertTrue("fra" in activeLangauges)
        self.assertEquals(self.form_model.label['fra'],
                          u'French Aids form_model')

    def test_should_delete_all_fields_from_document(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.delete_all_fields()
        self.assertEquals(len(form_model.fields), 0)

    def test_should_delete_all_fields_from_questions(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.delete_all_fields()
        self.assertEquals(len(form_model.fields), 0)

    def test_should_raise_exception_if_entity_field_already_exist(self):
        with self.assertRaises(EntityQuestionAlreadyExistsException):
            form_model = self.dbm.get(self.form_model__id, FormModel)
            question = TextField(name="added_question",
                                 code="Q5",
                                 label="How are you",
                                 entity_question_flag=True,
                                 ddtype=self.default_ddtype)
            form_model.add_field(question)
            form_model.save()

    def test_should_raise_exception_if_code_is_not_unique(self):
        with self.assertRaises(QuestionCodeAlreadyExistsException):
            form_model = self.dbm.get(self.form_model__id, FormModel)
            question = TextField(name="added_question",
                                 code="q1",
                                 label="How are you",
                                 ddtype=self.default_ddtype)
            form_model.add_field(question)
            form_model.save()

    def test_should_set_form_code(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.form_code = "xyz"
        self.assertEquals(form_model.form_code, "xyz")

    def test_should_persist_ddtype(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)

        self.assertEqual(form_model.fields[0].ddtype.slug,
                         self.default_ddtype.slug)
        self.assertEqual(form_model.fields[0].ddtype.id,
                         self.default_ddtype.id)
        self.assertEqual(form_model.fields[0].ddtype.name,
                         self.default_ddtype.name)

        self.assertEqual(form_model.fields[1].ddtype.slug,
                         self.default_ddtype.slug)
        self.assertEqual(form_model.fields[1].ddtype.id,
                         self.default_ddtype.id)
        self.assertEqual(form_model.fields[1].ddtype.name,
                         self.default_ddtype.name)

        self.assertEqual(form_model.fields[2].ddtype.slug,
                         self.default_ddtype.slug)
        self.assertEqual(form_model.fields[2].ddtype.id,
                         self.default_ddtype.id)
        self.assertEqual(form_model.fields[2].ddtype.name,
                         self.default_ddtype.name)

        self.assertEqual(form_model.fields[3].ddtype.slug,
                         self.default_ddtype.slug)
        self.assertEqual(form_model.fields[3].ddtype.id,
                         self.default_ddtype.id)
        self.assertEqual(form_model.fields[3].ddtype.name,
                         self.default_ddtype.name)

    def test_should_set_entity_type(self):
        form_model = self.dbm.get(self.form_model__id, FormModel)
        form_model.entity_id = "xyz"
        self.assertEquals(form_model.entity_id, "xyz")

    def test_should_create_a_questionnaire_from_dictionary(self):
        fields = [{
            "name": "What are you reporting on?",
            "defaultValue": "",
            "label": {
                "eng": "Entity being reported on"
            },
            "entity_question_flag": True,
            "type": "text",
            "ddtype": self.default_ddtype.to_json(),
            "code": "eid",
            "length": {
                "min": 1,
                "max": 10
            },
        }, {
            "range": {
                "max": 10,
                "min": 0
            },
            "label": {
                "eng": ""
            },
            "type": "integer",
            "ddtype": self.default_ddtype.to_json(),
            "name": "What is your age?",
            "code": "AGE"
        }, {
            "choices": [{
                "text": {
                    "eng": "Pune"
                }
            }, {
                "text": {
                    "eng": "Bangalore"
                }
            }],
            "label": {
                "eng": ""
            },
            "type":
            "select",
            "ddtype":
            self.default_ddtype.to_json(),
            "name":
            "Where do you live?",
            "code":
            "PLC"
        }]
        document = FormModelDocument()
        document.json_fields = fields
        document.entity_type = ["Reporter"]
        document.document_type = "FormModel"
        document.form_code = "F1"
        document.name = "New Project"
        document.type = "survey"
        document.type = "survey"
        entityQ = TextField(name="What are you reporting on?",
                            code="eid",
                            label="Entity being reported on",
                            entity_question_flag=True,
                            length=TextConstraint(min=1, max=10),
                            ddtype=self.default_ddtype)
        ageQ = IntegerField(name="What is your age?",
                            code="AGE",
                            label="",
                            range=NumericConstraint(min=0, max=10),
                            ddtype=self.default_ddtype)
        placeQ = SelectField(name="Where do you live?",
                             code="PLC",
                             label="",
                             options=[{
                                 "text": {
                                     "eng": "Pune"
                                 }
                             }, {
                                 "text": {
                                     "eng": "Bangalore"
                                 }
                             }],
                             single_select_flag=False,
                             ddtype=self.default_ddtype)
        questions = [entityQ, ageQ, placeQ]
        questionnaire = FormModel.new_from_doc(self.dbm, document)
        self.maxDiff = None
        self.assertListEqual(questionnaire.entity_type, ["Reporter"])
        self.assertEqual(questionnaire.name, "New Project")
        self.assertEqual(questionnaire.type, "survey")
        for i in range(len(questions)):
            self.assertEqual(questionnaire.fields[i]._to_json(),
                             questions[i]._to_json())

    def test_should_set_name(self):
        self.form_model.name = 'test_name'
        self.assertEquals(self.form_model.name, 'test_name')

    def test_should_set_entity_type_in_doc(self):
        self.form_model.entity_type = ["WaterPoint", "Dam"]
        self.assertEqual(self.form_model.entity_type, ["WaterPoint", "Dam"])

    def test_should_raise_exception_if_form_code_already_exists_on_creation(
            self):
        question1 = TextField(name="entity_question",
                              code="ID",
                              label="What is associated entity",
                              language="eng",
                              entity_question_flag=True,
                              ddtype=self.default_ddtype)
        form_model = FormModel(self.dbm,
                               entity_type=self.entity_type,
                               name="aids",
                               label="Aids form_model",
                               form_code="1",
                               type='survey',
                               fields=[question1])
        with self.assertRaises(DataObjectAlreadyExists):
            form_model.save()

    def test_should_raise_exception_if_form_code_already_exists_on_updation(
            self):
        question1 = TextField(name="entity_question",
                              code="ID",
                              label="What is associated entity",
                              language="eng",
                              entity_question_flag=True,
                              ddtype=self.default_ddtype)
        form_model2 = FormModel(self.dbm,
                                entity_type=self.entity_type,
                                name="aids",
                                label="Aids form_model",
                                form_code="2",
                                type='survey',
                                fields=[question1])
        form_model2.save()
        with self.assertRaises(DataObjectAlreadyExists):
            form_model2.form_code = "1"

    def test_should_not_raise_exception_if_form_code_is_updated(self):
        question1 = TextField(name="entity_question",
                              code="ID",
                              label="What is associated entity",
                              language="eng",
                              entity_question_flag=True,
                              ddtype=self.default_ddtype)
        form_model2 = FormModel(self.dbm,
                                entity_type=self.entity_type,
                                name="aids",
                                label="Aids form_model",
                                form_code="2",
                                type='survey',
                                fields=[question1])
        form_model2.save()
        form_model2.form_code = "2"
        form_model2.save()

    def test_to_html(self):
        expected_html = """<input id=id_entity_question name=entity_question class=class_entity_question type="text"/><input id=id_question1_Name name=question1_Name class=class_question1_Name type="text"/><input id=id_Father's age name=Father's age class=class_Father's age type="text"/><select name="Color" ><option value="1">RED</option><option value="2">YELLOW</option></select>"""
        self.assertEqual(expected_html, to_html(self.form_model))

    def _create_form_model(self):
        self.entity_type = ["HealthFacility", "Clinic"]
        define_type(self.dbm, ["HealthFacility", "Clinic"])
        self.default_ddtype = DataDictType(self.dbm,
                                           name='Default String Datadict Type',
                                           slug='string_default',
                                           primitive_type='string')
        self.default_ddtype.save()
        question1 = TextField(name="entity_question",
                              code="ID",
                              label="What is associated entity",
                              language="eng",
                              entity_question_flag=True,
                              ddtype=self.default_ddtype)
        question2 = TextField(name="question1_Name",
                              code="Q1",
                              label="What is your name",
                              defaultValue="some default value",
                              language="eng",
                              length=TextConstraint(5, 10),
                              ddtype=self.default_ddtype)
        question3 = IntegerField(name="Father's age",
                                 code="Q2",
                                 label="What is your Father's Age",
                                 range=NumericConstraint(min=15, max=120),
                                 ddtype=self.default_ddtype)
        question4 = SelectField(name="Color",
                                code="Q3",
                                label="What is your favourite color",
                                options=[("RED", 1), ("YELLOW", 2)],
                                ddtype=self.default_ddtype)
        self.form_model = FormModel(
            self.dbm,
            entity_type=self.entity_type,
            name="aids",
            label="Aids form_model",
            form_code="1",
            type='survey',
            fields=[question1, question2, question3, question4])
        self.form_model__id = self.form_model.save()
Exemple #13
0
class TestShouldSaveSMSSubmission(unittest.TestCase):
    def setUp(self):
        self.dbm = get_db_manager(database='mangrove-test')
        initializer.run(self.dbm)
        define_type(self.dbm, ["dog"])
        self.entity_type = ["healthfacility", "clinic"]
        define_type(self.dbm, self.entity_type)
        self.name_type = DataDictType(self.dbm,
                                      name='Name',
                                      slug='name',
                                      primitive_type='string')
        self.telephone_number_type = DataDictType(self.dbm,
                                                  name='telephone_number',
                                                  slug='telephone_number',
                                                  primitive_type='string')
        self.entity_id_type = DataDictType(self.dbm,
                                           name='Entity Id Type',
                                           slug='entity_id',
                                           primitive_type='string')
        self.stock_type = DataDictType(self.dbm,
                                       name='Stock Type',
                                       slug='stock',
                                       primitive_type='integer')
        self.color_type = DataDictType(self.dbm,
                                       name='Color Type',
                                       slug='color',
                                       primitive_type='string')

        self.name_type.save()
        self.telephone_number_type.save()
        self.stock_type.save()
        self.color_type.save()

        self.entity = create_entity(
            self.dbm,
            entity_type=self.entity_type,
            location=["India", "Pune"],
            aggregation_paths=None,
            short_code="cli1",
        )

        self.data_record_id = self.entity.add_data(
            data=[("Name", "Ruby", self.name_type)],
            submission=dict(submission_id="1"))

        self.reporter = create_entity(
            self.dbm,
            entity_type=["reporter"],
            location=["India", "Pune"],
            aggregation_paths=None,
            short_code="rep1",
        )

        self.reporter.add_data(data=[
            (MOBILE_NUMBER_FIELD, '1234', self.telephone_number_type),
            (NAME_FIELD, "Test_reporter", self.name_type)
        ],
                               submission=dict(submission_id="2"))

        question1 = TextField(name="entity_question",
                              code="EID",
                              label="What is associated entity",
                              language="eng",
                              entity_question_flag=True,
                              ddtype=self.entity_id_type)
        question2 = TextField(name="Name",
                              code="NAME",
                              label="Clinic Name",
                              defaultValue="some default value",
                              language="eng",
                              length=TextConstraint(4, 15),
                              ddtype=self.name_type)
        question3 = IntegerField(name="Arv stock",
                                 code="ARV",
                                 label="ARV Stock",
                                 range=NumericConstraint(min=15, max=120),
                                 ddtype=self.stock_type)
        question4 = SelectField(name="Color",
                                code="COL",
                                label="Color",
                                options=[("RED", 1), ("YELLOW", 2)],
                                ddtype=self.color_type)

        self.form_model = FormModel(self.dbm,
                                    entity_type=self.entity_type,
                                    name="aids",
                                    label="Aids form_model",
                                    form_code="clinic",
                                    type='survey',
                                    fields=[question1, question2, question3])
        self.form_model.add_field(question4)
        self.form_model__id = self.form_model.save()

        self.submission_handler = SubmissionHandler(self.dbm)
        self.sms_player = SMSPlayer(self.dbm, self.submission_handler,
                                    LocationTree())

    def tearDown(self):
        _delete_db_and_remove_db_manager(self.dbm)

    def send_sms(self, text):
        transport_info = TransportInfo(transport="sms",
                                       source="1234",
                                       destination="5678")
        response = self.sms_player.accept(
            Request(transportInfo=transport_info, message=text))
        return response

    def test_should_save_submitted_sms(self):
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % self.entity.short_code

        response = self.send_sms(text)

        self.assertTrue(response.success)

        data_record_id = response.datarecord_id
        data_record = self.dbm._load_document(
            id=data_record_id, document_class=DataRecordDocument)
        self.assertEqual(self.name_type.slug,
                         data_record.data["Name"]["type"]["slug"])
        self.assertEqual(self.stock_type.slug,
                         data_record.data["Arv stock"]["type"]["slug"])
        self.assertEqual(self.color_type.slug,
                         data_record.data["Color"]["type"]["slug"])
        self.assertEqual("clinic", data_record.submission['form_code'])
        self.assertEqual(u"Test_reporter",
                         response.reporters[0].get(NAME_FIELD))

        data = self.entity.values({
            "Name": "latest",
            "Arv stock": "latest",
            "Color": "latest"
        })
        self.assertEquals(data["Arv stock"], 50)
        self.assertEquals(data["Name"], "CLINIC-MADA")
        submission_log = self.dbm._load_document(response.submission_id,
                                                 SubmissionLogDocument)
        self.assertEquals(data_record_id, submission_log.data_record_id)

    def test_should_save_submitted_sms_for_activity_report(self):
        question1 = TextField(name="entity_question",
                              code="EID",
                              label="What is associated entity",
                              language="eng",
                              entity_question_flag=True,
                              ddtype=self.entity_id_type)
        question2 = TextField(name="Name",
                              code="NAME",
                              label="Clinic Name",
                              defaultValue="some default value",
                              language="eng",
                              length=TextConstraint(4, 15),
                              ddtype=self.name_type)
        question3 = IntegerField(name="Arv stock",
                                 code="ARV",
                                 label="ARV Stock",
                                 range=NumericConstraint(min=15, max=120),
                                 ddtype=self.stock_type)
        activity_report = FormModel(self.dbm,
                                    entity_type=["reporter"],
                                    name="report",
                                    label="reporting form_model",
                                    form_code="acp",
                                    type='survey',
                                    fields=[question1, question2, question3])
        activity_report.save()

        text = "acp +name tester +ARV 50 "

        response = self.send_sms(text)

        self.assertTrue(response.success)
        self.assertEqual(u"Test_reporter",
                         response.reporters[0].get(NAME_FIELD))

        data_record_id = response.datarecord_id
        data_record = self.dbm._load_document(
            id=data_record_id, document_class=DataRecordDocument)
        self.assertEqual(self.name_type.slug,
                         data_record.data["Name"]["type"]["slug"])
        self.assertEqual(self.stock_type.slug,
                         data_record.data["Arv stock"]["type"]["slug"])
        self.assertEqual("acp", data_record.submission['form_code'])
        data = self.reporter.values({"Name": "latest", "Arv stock": "latest"})
        self.assertEquals(data["Arv stock"], 50)
        self.assertEquals(data["Name"], "tester")
        submission_log = self.dbm._load_document(response.submission_id,
                                                 SubmissionLogDocument)
        self.assertEquals(data_record_id, submission_log.data_record_id)

    def test_should_give_error_for_wrong_integer_value(self):
        text = "clinic +EID %s +ARV 150 " % self.entity.id
        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual(len(response.errors), 1)

    def test_should_give_error_for_wrong_text_value(self):
        text = "clinic +EID CID001 +NAME ABC"

        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual(len(response.errors), 1)

    def test_get_submissions_for_form(self):
        self.dbm._save_document(
            SubmissionLogDocument(channel="transport",
                                  source=1234,
                                  destination=12345,
                                  form_code="abc",
                                  values={
                                      'Q1': 'ans1',
                                      'Q2': 'ans2'
                                  },
                                  status=False,
                                  error_message="",
                                  data_record_id='2345678'))
        self.dbm._save_document(
            SubmissionLogDocument(channel="transport",
                                  source=1234,
                                  destination=12345,
                                  form_code="abc",
                                  values={
                                      'Q1': 'ans12',
                                      'Q2': 'ans22'
                                  },
                                  status=False,
                                  error_message="",
                                  data_record_id='1234567'))
        self.dbm._save_document(
            SubmissionLogDocument(channel="transport",
                                  source=1234,
                                  destination=12345,
                                  form_code="def",
                                  values={
                                      'defQ1': 'defans12',
                                      'defQ2': 'defans22'
                                  },
                                  status=False,
                                  error_message="",
                                  data_record_id='345678'))

        oneDay = datetime.timedelta(days=1)
        tomorrow = datetime.datetime.now() + oneDay
        submission_list, ids = get_submissions_made_for_form(
            self.dbm, "abc", 0,
            int(mktime(tomorrow.timetuple())) * 1000)
        self.assertEquals(2, len(submission_list))
        self.assertEquals({
            'Q1': 'ans12',
            'Q2': 'ans22'
        }, submission_list[0]['values'])
        self.assertEquals({
            'Q1': 'ans1',
            'Q2': 'ans2'
        }, submission_list[1]['values'])
        self.assertEquals(2, len(ids))
        self.assertListEqual(['1234567', '2345678'], ids)

    def test_error_messages_are_being_logged_in_submissions(self):
        text = "clinic +EID %s +ARV 150 " % self.entity.id
        self.send_sms(text)
        oneDay = datetime.timedelta(days=1)
        tomorrow = datetime.datetime.now() + oneDay
        submission_list, ids = get_submissions_made_for_form(
            self.dbm, "clinic", 0,
            int(mktime(tomorrow.timetuple())) * 1000)
        self.assertEquals(1, len(submission_list))
        self.assertEquals(
            u"Answer 150 for question ARV is greater than allowed.",
            submission_list[0]['error_message'])

    def test_should_register_new_entity(self):
        message1 = """reg +t  dog +n  Clinic in Diégo–Suarez +l  Diégo–Suarez +g  -12.35  49.3  +d This is a Clinic in
        Diégo–Suarez + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = "dog1"
        self.assertEqual(response.short_code, expected_short_code)
        a = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual(a.short_code, expected_short_code)

        text = "reg +N buddy +S bud +T dog +G 80 80 +D its a dog! +M 45557"

        response = self.send_sms(text)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        self.assertEqual(response.short_code, "bud", ["dog"])
        a = get_by_short_code(self.dbm, "bud", ["dog"])
        self.assertEqual(a.short_code, "bud")

        text = "reg +N buddy2 +T dog +L 80 80 +D its another dog! +M 78541"

        response = self.send_sms(text)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = "dog3"
        self.assertEqual(response.short_code, expected_short_code)
        b = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual(b.short_code, expected_short_code)

    def test_should_return_error_for_registration_having_invalid_geo_data(
            self):
        INVALID_LATITUDE = 380
        text = "reg +N buddy2 +T dog +G %s 80 +D its another dog! +M 78541" % (
            INVALID_LATITUDE, )

        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual({'g': 'The answer 380 must be between -90 and 90'},
                         response.errors)

        INVALID_LONGITUDE = -184
        text = "reg +N buddy2 +T dog +G 80 %s +D its another dog! +M 78541" % (
            INVALID_LONGITUDE, )

        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual({'g': 'The answer -184 must be between -180 and 180'},
                         response.errors)

    def test_should_log_submission(self):
        transport_info = TransportInfo(transport="sms",
                                       source="1234",
                                       destination="5678")
        request = Request(transportInfo=transport_info,
                          message="reg +N buddy +S DOG3 +T dog")

        response = self.sms_player.accept(request)
        submission_log = self.dbm._load_document(response.submission_id,
                                                 SubmissionLogDocument)
        self.assertIsInstance(submission_log, SubmissionLogDocument)
        self.assertEquals(transport_info.transport, submission_log.channel)
        self.assertEquals(transport_info.source, submission_log.source)
        self.assertEquals(transport_info.destination,
                          submission_log.destination)
        self.assertEquals(True, submission_log.status)
        self.assertEquals("reg", submission_log.form_code)
        self.assertEquals({
            'n': 'buddy',
            's': 'DOG3',
            't': 'dog',
            'l': None
        }, submission_log.values)
        self.assertEquals(transport_info.destination,
                          submission_log.destination)
        self.assertEquals(response.datarecord_id,
                          submission_log.data_record_id)

    def test_should_throw_error_if_entity_with_same_short_code_exists(self):
        text = "reg +N buddy +S DOG3 +T dog +G 80 80 +D its a dog! +M 123456"
        self.send_sms(text)
        text = "reg +N buddy2 +S dog3 +T dog +L 80 80 +D its a dog! +M 123456"
        with self.assertRaises(DataObjectAlreadyExists):
            self.send_sms(text)

    def test_should_throw_error_if_reporter_with_same_phone_number_exists(
            self):
        text = "reg +N buddy +T reporter +G 80 80 +M 1@23456"
        self.send_sms(text)
        with self.assertRaises(MultipleReportersForANumberException):
            text = "reg +N buddy2 +T reporter +L 80 80 +M 123456"
            self.send_sms(text)

    def test_should_throw_error_if_reporter_registration_submission_has_no_mobile_number(
            self):
        with self.assertRaises(MobileNumberMissing):
            text = "reg +N buddy2 +T reporter +L 80 80"
            self.send_sms(text)

    def test_should_throw_error_if_entityType_doesnt_exist(self):
        with self.assertRaises(EntityTypeDoesNotExistsException):
            text = "reg +N buddy1 +S DOG3 +T cat +L 80 80 +D its another dog! +M 1234567"
            self.send_sms(text)

    def test_entity_instance_is_case_insensitive(self):
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % "CLI1"

        response = self.send_sms(text)

        self.assertTrue(response.success)

    def test_questionnaire_code_is_case_insensitive(self):
        text = "CLINIC +EID %s +name CLINIC-MADA +ARV 50 +COL a" % "cli1"
        response = self.send_sms(text)
        self.assertTrue(response.success)

    def test_entity_type_is_case_insensitive_in_registration(self):
        text = "reg +n buddy +T DOG +G 80 80 +M 123456"
        response = self.send_sms(text)
        self.assertTrue(response.success)
        data_record = self.dbm._load_document(response.datarecord_id,
                                              DataRecordDocument)
        actual_type = data_record["entity"]["aggregation_paths"]["_type"]
        self.assertEquals(["dog"], actual_type)

    def test_should_accept_unicode_submissions(self):
        text = "reg +s Āgra +n Agra +m 080 +t clinic +g 45 56"
        with self.assertRaises(EntityTypeDoesNotExistsException):
            self.send_sms(text)

    def test_should_accept_unicode_submissions_and_invalidate_wrong_GPS(self):
        text = "reg +s Āgra +n Agra +m 080 +t clinic +g 45Ö 56"
        with self.assertRaises(GeoCodeFormatException):
            self.send_sms(text)

    def test_should_raise_exception_for_inactive_form_model(self):
        self.form_model.deactivate()
        self.form_model.save()
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % self.entity.short_code
        with self.assertRaises(InactiveFormModelException):
            self.send_sms(text)

    def test_should_set_submission_log_as_Test_for_form_model_in_test_mode(
            self):
        self.form_model.set_test_mode()
        self.form_model.save()
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % self.entity.short_code
        response = self.send_sms(text)

        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        self.assertIsNotNone(response.submission_id)
        submission_log = self.dbm._load_document(response.submission_id,
                                                 SubmissionLogDocument)
        self.assertTrue(submission_log.test)

    def test_should_register_entity_with_geo_code(self):
        message1 = """reg +t dog +n Dog in Diégo–Suarez +g -12.35  49.3  +d This is a Dog in
        Diégo–Suarez + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = 'dog1'
        self.assertEqual(response.short_code, expected_short_code)
        dog = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual([-12.35, 49.3], dog.geometry.get("coordinates"))

    def test_should_register_entity_with_geocode_if_only_location_provided(
            self):
        message1 = """reg +t dog +n Dog in AMPIZARANTANY +l AMPIZARANTANY +d This is a Dog in
        AMPIZARANTANY + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = 'dog1'
        self.assertEqual(response.short_code, expected_short_code)
        dog = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual([-12, 60], dog.geometry.get("coordinates"))

    def test_should_register_entity_with_geocode_and_location_provided(self):
        message1 = """reg +t dog +n Dog in AMPIZARANTANY +l AMPIZARANTANY +g 10 10 +d This is a Dog in
        AMPIZARANTANY + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = 'dog1'
        self.assertEqual(response.short_code, expected_short_code)
        dog = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual([10, 10], dog.geometry.get("coordinates"))
        self.assertEqual(["ampizarantany"], dog.location_path)
class TestShouldSaveSMSSubmission(unittest.TestCase):
    def setUp(self):
        self.dbm = get_db_manager(database='mangrove-test')
        initializer.run(self.dbm)
        define_type(self.dbm, ["dog"])
        self.entity_type = ["healthfacility", "clinic"]
        define_type(self.dbm, self.entity_type)
        self.name_type = DataDictType(self.dbm, name='Name', slug='name', primitive_type='string')
        self.telephone_number_type = DataDictType(self.dbm, name='telephone_number', slug='telephone_number',
                                                  primitive_type='string')
        self.entity_id_type = DataDictType(self.dbm, name='Entity Id Type', slug='entity_id', primitive_type='string')
        self.stock_type = DataDictType(self.dbm, name='Stock Type', slug='stock', primitive_type='integer')
        self.color_type = DataDictType(self.dbm, name='Color Type', slug='color', primitive_type='string')

        self.name_type.save()
        self.telephone_number_type.save()
        self.stock_type.save()
        self.color_type.save()

        self.entity = create_entity(self.dbm, entity_type=self.entity_type,
                                    location=["India", "Pune"], aggregation_paths=None, short_code="cli1",
                                    )

        self.data_record_id = self.entity.add_data(data=[("Name", "Ruby", self.name_type)],
                                                   submission=dict(submission_id="1"))

        self.reporter = create_entity(self.dbm, entity_type=["reporter"],
                                      location=["India", "Pune"], aggregation_paths=None, short_code="rep1",
                                      )

        self.reporter.add_data(data=[(MOBILE_NUMBER_FIELD, '1234', self.telephone_number_type),
                (NAME_FIELD, "Test_reporter", self.name_type)], submission=dict(submission_id="2"))

        question1 = TextField(name="entity_question", code="EID", label="What is associated entity",
                              language="eng", entity_question_flag=True, ddtype=self.entity_id_type)
        question2 = TextField(name="Name", code="NAME", label="Clinic Name",
                              defaultValue="some default value", language="eng", length=TextConstraint(4, 15),
                              ddtype=self.name_type)
        question3 = IntegerField(name="Arv stock", code="ARV", label="ARV Stock",
                                 range=NumericConstraint(min=15, max=120), ddtype=self.stock_type)
        question4 = SelectField(name="Color", code="COL", label="Color",
                                options=[("RED", 1), ("YELLOW", 2)], ddtype=self.color_type)

        self.form_model = FormModel(self.dbm, entity_type=self.entity_type, name="aids", label="Aids form_model",
                                    form_code="clinic", type='survey', fields=[question1, question2, question3])
        self.form_model.add_field(question4)
        self.form_model__id = self.form_model.save()

        self.submission_handler = SubmissionHandler(self.dbm)
        self.sms_player = SMSPlayer(self.dbm, self.submission_handler, LocationTree())

    def tearDown(self):
        _delete_db_and_remove_db_manager(self.dbm)

    def send_sms(self, text):
        transport_info = TransportInfo(transport="sms", source="1234", destination="5678")
        response = self.sms_player.accept(Request(transportInfo=transport_info, message=text))
        return response

    def test_should_save_submitted_sms(self):
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % self.entity.short_code

        response = self.send_sms(text)

        self.assertTrue(response.success)

        data_record_id = response.datarecord_id
        data_record = self.dbm._load_document(id=data_record_id, document_class=DataRecordDocument)
        self.assertEqual(self.name_type.slug, data_record.data["Name"]["type"]["slug"])
        self.assertEqual(self.stock_type.slug, data_record.data["Arv stock"]["type"]["slug"])
        self.assertEqual(self.color_type.slug, data_record.data["Color"]["type"]["slug"])
        self.assertEqual("clinic", data_record.submission['form_code'])
        self.assertEqual(u"Test_reporter",response.reporters[0].get(NAME_FIELD))

        data = self.entity.values({"Name": "latest", "Arv stock": "latest", "Color": "latest"})
        self.assertEquals(data["Arv stock"], 50)
        self.assertEquals(data["Name"], "CLINIC-MADA")
        submission_log = self.dbm._load_document(response.submission_id, SubmissionLogDocument)
        self.assertEquals(data_record_id, submission_log.data_record_id)

    def test_should_save_submitted_sms_for_activity_report(self):
        question1 = TextField(name="entity_question", code="EID", label="What is associated entity",
                              language="eng", entity_question_flag=True, ddtype=self.entity_id_type)
        question2 = TextField(name="Name", code="NAME", label="Clinic Name",
                              defaultValue="some default value", language="eng", length=TextConstraint(4, 15),
                              ddtype=self.name_type)
        question3 = IntegerField(name="Arv stock", code="ARV", label="ARV Stock",
                                 range=NumericConstraint(min=15, max=120), ddtype=self.stock_type)
        activity_report = FormModel(self.dbm, entity_type=["reporter"], name="report", label="reporting form_model",
                                    form_code="acp", type='survey', fields=[question1, question2, question3])
        activity_report.save()

        text = "acp +name tester +ARV 50 "

        response = self.send_sms(text)

        self.assertTrue(response.success)
        self.assertEqual(u"Test_reporter",response.reporters[0].get(NAME_FIELD))

        data_record_id = response.datarecord_id
        data_record = self.dbm._load_document(id=data_record_id, document_class=DataRecordDocument)
        self.assertEqual(self.name_type.slug, data_record.data["Name"]["type"]["slug"])
        self.assertEqual(self.stock_type.slug, data_record.data["Arv stock"]["type"]["slug"])
        self.assertEqual("acp", data_record.submission['form_code'])
        data = self.reporter.values({"Name": "latest", "Arv stock": "latest"})
        self.assertEquals(data["Arv stock"], 50)
        self.assertEquals(data["Name"], "tester")
        submission_log = self.dbm._load_document(response.submission_id, SubmissionLogDocument)
        self.assertEquals(data_record_id, submission_log.data_record_id)

    def test_should_give_error_for_wrong_integer_value(self):
        text = "clinic +EID %s +ARV 150 " % self.entity.id
        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual(len(response.errors), 1)

    def test_should_give_error_for_wrong_text_value(self):
        text = "clinic +EID CID001 +NAME ABC"

        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual(len(response.errors), 1)

    def test_get_submissions_for_form(self):
        self.dbm._save_document(SubmissionLogDocument(channel="transport", source=1234,
                                                      destination=12345, form_code="abc",
                                                      values={'Q1': 'ans1', 'Q2': 'ans2'},
                                                      status=False, error_message="", data_record_id='2345678'))
        self.dbm._save_document(SubmissionLogDocument(channel="transport", source=1234,
                                                      destination=12345, form_code="abc",
                                                      values={'Q1': 'ans12', 'Q2': 'ans22'},
                                                      status=False, error_message="", data_record_id='1234567'))
        self.dbm._save_document(SubmissionLogDocument(channel="transport", source=1234,
                                                      destination=12345, form_code="def",
                                                      values={'defQ1': 'defans12', 'defQ2': 'defans22'},
                                                      status=False, error_message="", data_record_id='345678'))

        oneDay = datetime.timedelta(days=1)
        tomorrow = datetime.datetime.now() + oneDay
        submission_list, ids = get_submissions_made_for_form(self.dbm, "abc", 0,
                                                             int(mktime(tomorrow.timetuple())) * 1000)
        self.assertEquals(2, len(submission_list))
        self.assertEquals({'Q1': 'ans12', 'Q2': 'ans22'}, submission_list[0]['values'])
        self.assertEquals({'Q1': 'ans1', 'Q2': 'ans2'}, submission_list[1]['values'])
        self.assertEquals(2, len(ids))
        self.assertListEqual(['1234567', '2345678'], ids)

    def test_error_messages_are_being_logged_in_submissions(self):
        text = "clinic +EID %s +ARV 150 " % self.entity.id
        self.send_sms(text)
        oneDay = datetime.timedelta(days=1)
        tomorrow = datetime.datetime.now() + oneDay
        submission_list, ids = get_submissions_made_for_form(self.dbm, "clinic", 0,
                                                             int(mktime(tomorrow.timetuple())) * 1000)
        self.assertEquals(1, len(submission_list))
        self.assertEquals(u"Answer 150 for question ARV is greater than allowed.", submission_list[0]['error_message'])


    def test_should_register_new_entity(self):
        message1 = """reg +t  dog +n  Clinic in Diégo–Suarez +l  Diégo–Suarez +g  -12.35  49.3  +d This is a Clinic in
        Diégo–Suarez + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = "dog1"
        self.assertEqual(response.short_code, expected_short_code)
        a = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual(a.short_code, expected_short_code)

        text = "reg +N buddy +S bud +T dog +G 80 80 +D its a dog! +M 45557"

        response = self.send_sms(text)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        self.assertEqual(response.short_code, "bud", ["dog"])
        a = get_by_short_code(self.dbm, "bud", ["dog"])
        self.assertEqual(a.short_code, "bud")

        text = "reg +N buddy2 +T dog +L 80 80 +D its another dog! +M 78541"

        response = self.send_sms(text)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = "dog3"
        self.assertEqual(response.short_code, expected_short_code)
        b = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual(b.short_code, expected_short_code)

    def test_should_return_error_for_registration_having_invalid_geo_data(self):
        INVALID_LATITUDE = 380
        text = "reg +N buddy2 +T dog +G %s 80 +D its another dog! +M 78541" % (INVALID_LATITUDE,)

        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual({'g': 'The answer 380 must be between -90 and 90'}, response.errors)

        INVALID_LONGITUDE = -184
        text = "reg +N buddy2 +T dog +G 80 %s +D its another dog! +M 78541" % (INVALID_LONGITUDE,)

        response = self.send_sms(text)
        self.assertFalse(response.success)
        self.assertEqual({'g': 'The answer -184 must be between -180 and 180'}, response.errors)

    def test_should_log_submission(self):
        transport_info = TransportInfo(transport="sms", source="1234", destination="5678")
        request = Request(transportInfo=transport_info, message="reg +N buddy +S DOG3 +T dog")

        response = self.sms_player.accept(request)
        submission_log = self.dbm._load_document(response.submission_id, SubmissionLogDocument)
        self.assertIsInstance(submission_log, SubmissionLogDocument)
        self.assertEquals(transport_info.transport, submission_log.channel)
        self.assertEquals(transport_info.source, submission_log.source)
        self.assertEquals(transport_info.destination, submission_log.destination)
        self.assertEquals(True, submission_log. status)
        self.assertEquals("reg", submission_log.form_code)
        self.assertEquals({'n': 'buddy', 's': 'DOG3', 't': 'dog', 'l':None}, submission_log.values)
        self.assertEquals(transport_info.destination, submission_log.destination)
        self.assertEquals(response.datarecord_id, submission_log.data_record_id)


    def test_should_throw_error_if_entity_with_same_short_code_exists(self):
        text = "reg +N buddy +S DOG3 +T dog +G 80 80 +D its a dog! +M 123456"
        self.send_sms(text)
        text = "reg +N buddy2 +S dog3 +T dog +L 80 80 +D its a dog! +M 123456"
        with self.assertRaises(DataObjectAlreadyExists):
            self.send_sms(text)

    def test_should_throw_error_if_reporter_with_same_phone_number_exists(self):
        text = "reg +N buddy +T reporter +G 80 80 +M 1@23456"
        self.send_sms(text)
        with self.assertRaises(MultipleReportersForANumberException):
            text = "reg +N buddy2 +T reporter +L 80 80 +M 123456"
            self.send_sms(text)

    def test_should_throw_error_if_reporter_registration_submission_has_no_mobile_number(self):
        with self.assertRaises(MobileNumberMissing):
            text = "reg +N buddy2 +T reporter +L 80 80"
            self.send_sms(text)

    def test_should_throw_error_if_entityType_doesnt_exist(self):
        with self.assertRaises(EntityTypeDoesNotExistsException):
            text = "reg +N buddy1 +S DOG3 +T cat +L 80 80 +D its another dog! +M 1234567"
            self.send_sms(text)

    def test_entity_instance_is_case_insensitive(self):
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % "CLI1"

        response = self.send_sms(text)

        self.assertTrue(response.success)

    def test_questionnaire_code_is_case_insensitive(self):
        text = "CLINIC +EID %s +name CLINIC-MADA +ARV 50 +COL a" % "cli1"
        response = self.send_sms(text)
        self.assertTrue(response.success)

    def test_entity_type_is_case_insensitive_in_registration(self):
        text = "reg +n buddy +T DOG +G 80 80 +M 123456"
        response = self.send_sms(text)
        self.assertTrue(response.success)
        data_record = self.dbm._load_document(response.datarecord_id, DataRecordDocument)
        actual_type = data_record["entity"]["aggregation_paths"]["_type"]
        self.assertEquals(["dog"], actual_type)

    def test_should_accept_unicode_submissions(self):
        text = "reg +s Āgra +n Agra +m 080 +t clinic +g 45 56"
        with self.assertRaises(EntityTypeDoesNotExistsException):
            self.send_sms(text)

    def test_should_accept_unicode_submissions_and_invalidate_wrong_GPS(self):
        text = "reg +s Āgra +n Agra +m 080 +t clinic +g 45Ö 56"
        with self.assertRaises(GeoCodeFormatException):
            self.send_sms(text)

    def test_should_raise_exception_for_inactive_form_model(self):
        self.form_model.deactivate()
        self.form_model.save()
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % self.entity.short_code
        with self.assertRaises(InactiveFormModelException):
            self.send_sms(text)

    def test_should_set_submission_log_as_Test_for_form_model_in_test_mode(self):
        self.form_model.set_test_mode()
        self.form_model.save()
        text = "clinic +EID %s +name CLINIC-MADA +ARV 50 +COL a" % self.entity.short_code
        response = self.send_sms(text)

        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        self.assertIsNotNone(response.submission_id)
        submission_log = self.dbm._load_document(response.submission_id, SubmissionLogDocument)
        self.assertTrue(submission_log.test)


    def test_should_register_entity_with_geo_code(self):
        message1 = """reg +t dog +n Dog in Diégo–Suarez +g -12.35  49.3  +d This is a Dog in
        Diégo–Suarez + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = 'dog1'
        self.assertEqual(response.short_code, expected_short_code)
        dog = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual([-12.35 , 49.3] ,dog.geometry.get("coordinates"))

    def test_should_register_entity_with_geocode_if_only_location_provided(self):
        message1 = """reg +t dog +n Dog in AMPIZARANTANY +l AMPIZARANTANY +d This is a Dog in
        AMPIZARANTANY + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = 'dog1'
        self.assertEqual(response.short_code, expected_short_code)
        dog = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual([-12, 60] ,dog.geometry.get("coordinates"))

    def test_should_register_entity_with_geocode_and_location_provided(self):
        message1 = """reg +t dog +n Dog in AMPIZARANTANY +l AMPIZARANTANY +g 10 10 +d This is a Dog in
        AMPIZARANTANY + m
        87654325
        """
        response = self.send_sms(message1)
        self.assertTrue(response.success)
        self.assertIsNotNone(response.datarecord_id)
        expected_short_code = 'dog1'
        self.assertEqual(response.short_code, expected_short_code)
        dog = get_by_short_code(self.dbm, expected_short_code, ["dog"])
        self.assertEqual([10, 10] ,dog.geometry.get("coordinates"))
        self.assertEqual(["ampizarantany"] ,dog.location_path)