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 test_should_convert_to_json(self):
     _id = "1"
     name_type = DataDictType(self.dbm, name='First name', slug='first_Name', primitive_type='string', id=_id)
     expected_json = {'_id': _id,
                      'constraints': {},
                      'created': '2010-01-01T10:11:12+00:00',
                      'description': None,
                      'document_type': u'DataDict',
                      'modified': None,
                      'name': u'First name',
                      'primitive_type': u'string',
                      'slug': u'first_Name',
                      'tags': [],
                      'void': False}
     self.assertEqual(expected_json, name_type.to_json())
Beispiel #3
0
def create_question_from(dictionary, dbm):
    """
     Given a dictionary that defines a question, this would create a field with all the validations that are
     defined on it.
    """
    type = dictionary.get("type")
    name = dictionary.get("name")
    code = dictionary.get("code")
    is_entity_question = dictionary.get("entity_question_flag")
    label_dict = dictionary.get("label")
    instruction = dictionary.get("instruction")
    label = None
    if label_dict is not None:
        label = label_dict.get(field_attributes.DEFAULT_LANGUAGE)
    ddtype = DataDictType.create_from_json(dictionary.get("ddtype"), dbm)
    if type == field_attributes.TEXT_FIELD:
        return _get_text_field(code, ddtype, dictionary, is_entity_question, label, name, instruction=instruction)
    elif type == field_attributes.INTEGER_FIELD:
        return _get_integer_field(code, ddtype, dictionary, label, name, instruction=instruction)
    elif type == field_attributes.DATE_FIELD:
        return _get_date_field(code, ddtype, dictionary, label, name, instruction=instruction)
    elif type == field_attributes.LOCATION_FIELD:
        return GeoCodeField(name=name, code=code, label=label, ddtype=ddtype, instruction=instruction)
    elif type == field_attributes.SELECT_FIELD or type == field_attributes.MULTISELECT_FIELD:
        return _get_select_field(code, ddtype, dictionary, label, name, type, instruction=instruction)
    elif type == field_attributes.LIST_FIELD:
        return _get_list_field(name, code, label, ddtype, instruction=instruction)
    return None
 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_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_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()
    def test_should_create_from_json(self):
        _id = "1"
        first_name = u'First name'
        primitive_type = u'string'
        slug = u'first_Name'
        json = {'_id': _id,
                'constraints': {},
                'created': '2010-01-01T10:11:12+00:00',
                'description': None,
                'document_type': u'DataDict',
                'modified': None,
                'name': first_name,
                'primitive_type': primitive_type,
                'slug': slug,
                'tags': [],
                'void': False}

        ddtype = DataDictType.create_from_json(json, self.dbm)
        self.assertEqual(_id, ddtype.id)
        self.assertEqual(first_name, ddtype.name)
        self.assertEqual(primitive_type, ddtype.primitive_type)
        self.assertEqual(slug, ddtype.slug)
        self.assertEqual({}, ddtype.constraints)
        self.assertEqual([], ddtype.tags)
 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)
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()
Beispiel #10
0
    def test_should_format_error_message(self):
        test_data_list = [{
            "expected_reply":
            [("en",
              u"Error. Incorrect answer for question 1. Please review printed Questionnaire and resend entire SMS."
              ),
             ("fr",
              u"Erreur. Reponse incorrecte pour la question 1. Veuillez revoir le Questionnaire rempli et renvoyez tout le SMS corrige."
              ),
             ("mg",
              u"Diso ny valin’ny fanontaniana faha-1. Jereo ny lisitry ny fanontaniana azafady dia avereno alefa manontolo ny SMS marina."
              )],
            "errors": {
                "N": "Some error"
            }
        }, {
            "expected_reply":
            [("en",
              u"Error. Incorrect answer for question 1 and 2. Please review printed Questionnaire and resend entire SMS."
              ),
             ("fr",
              u"Erreur. Reponse incorrecte pour les questions 1 et 2. Veuillez revoir le Questionnaire rempli et renvoyez tout le SMS corrige."
              ),
             ("mg",
              u"Diso ny valin’ny fanontaniana faha-1 sy faha-2. Jereo ny lisitry ny fanontaniana azafady dia avereno alefa manontolo ny SMS marina."
              )],
            "errors": {
                "FA": "Some error",
                "n": "Some other error"
            }
        }, {
            "expected_reply":
            [("en",
              u"Error. Incorrect answer for question 1, 2 and 3. Please review printed Questionnaire and resend entire SMS."
              ),
             ("fr",
              u"Erreur. Reponse incorrecte pour les questions 1, 2 et 3. Veuillez revoir le Questionnaire rempli et renvoyez tout le SMS corrige."
              ),
             ("mg",
              u"Diso ny valin’ny fanontaniana faha-1 sy faha-2 ary faha-3. Jereo ny lisitry ny fanontaniana azafady dia avereno alefa manontolo ny SMS marina."
              )],
            "errors": {
                "Fa": "Some error",
                "n": "Some other error",
                "pl": "Sp"
            }
        }]

        response = Mock()
        response.is_registration = False
        current_lg = get_language()
        default_ddtype = DataDictType(Mock(spec=DatabaseManager),
                                      name='Default String Datadict Type',
                                      slug='string_default',
                                      primitive_type='string')
        form_model_mock = Mock(spec=FormModel,
                               fields=[
                                   TextField("name", "n", "Father's name",
                                             default_ddtype),
                                   TextField("age", "fa", "Father's age",
                                             default_ddtype),
                                   TextField("place", "pl", "Father's Place",
                                             default_ddtype)
                               ])
        for test_data in test_data_list:
            response.errors = test_data.get("errors")
            for (lg, expected_message) in test_data.get("expected_reply"):
                activate(lg)
                message = get_submission_error_message_for(
                    response, form_model=form_model_mock)
                self.assertEqual(expected_message, message)
        activate(current_lg)
        self.assertEqual(current_lg, get_language())
Beispiel #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()
Beispiel #12
0
    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))
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()
Beispiel #14
0
    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())
Beispiel #15
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)
 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
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)