def set_up_form(cls): cls.form_id = uuid4().hex user_id = uuid4().hex case_update = { 'year': '1970', 'breakfast': 'spam egg spam spam bacon spam', 'decimal': '4.4', } builder = FormSubmissionBuilder( form_id=cls.form_id, form_properties={ 'name': 'spam', **case_update, }, case_blocks=[ CaseBlock(case_id=uuid4().hex, create=True, case_type='sketch', case_name='spam', owner_id=user_id, update=case_update) ], metadata=TestFormMetadata( domain=cls.domain, user_id=user_id, ), ) submit_form_locally(builder.as_xml_string(), cls.domain) cls.form = FormAccessors(cls.domain).get_form(cls.form_id)
def test_update_responses(self): formxml = FormSubmissionBuilder(form_id='123', form_properties={ 'breakfast': 'toast', 'lunch': 'sandwich' }).as_xml_string() pic = UploadedFile(BytesIO(b"fake"), 'pic.jpg', content_type='image/jpeg') xform = submit_form_locally(formxml, DOMAIN, attachments={ "image": pic }).xform updates = {'breakfast': 'fruit'} errors = FormProcessorInterface(DOMAIN).update_responses( xform, updates, 'user1') form = FormAccessors(DOMAIN).get_form(xform.form_id) self.assertEqual(0, len(errors)) self.assertEqual('fruit', form.form_data['breakfast']) self.assertEqual('sandwich', form.form_data['lunch']) self.assertIn("image", form.attachments) self.assertEqual(form.get_attachment("image"), b"fake") self.assertXmlEqual( form.get_attachment("form.xml").decode('utf-8'), formxml.replace("toast", "fruit"), )
def form_context(form_ids): for form_id in form_ids: builder = FormSubmissionBuilder( form_id=form_id, metadata=TestFormMetadata(domain=DOMAIN), ) submit_form_locally(builder.as_xml_string(), DOMAIN) try: yield finally: XFormInstance.objects.hard_delete_forms(DOMAIN, form_ids)
def test_update_responses_error(self): formxml = FormSubmissionBuilder( form_id='123', form_properties={'nine': 'nueve'} ).as_xml_string() xform = submit_form_locally(formxml, DOMAIN).xform updates = {'eight': 'ocho'} errors = FormProcessorInterface(DOMAIN).update_responses(xform, updates, 'user1') self.assertEqual(['eight'], errors)
def test_update_responses(self): formxml = FormSubmissionBuilder( form_id='123', form_properties={'breakfast': 'toast', 'lunch': 'sandwich'} ).as_xml_string() pic = UploadedFile(BytesIO(b"fake"), 'pic.jpg', content_type='image/jpeg') xform = submit_form_locally(formxml, DOMAIN, attachments={"image": pic}).xform updates = {'breakfast': 'fruit'} errors = FormProcessorInterface(DOMAIN).update_responses(xform, updates, 'user1') form = FormAccessors(DOMAIN).get_form(xform.form_id) self.assertEqual(0, len(errors)) self.assertEqual('fruit', form.form_data['breakfast']) self.assertEqual('sandwich', form.form_data['lunch']) self.assertIn("image", form.attachments) self.assertEqual(form.get_attachment("image"), b"fake") self.assertXmlEqual( form.get_attachment("form.xml").decode('utf-8'), formxml.replace("toast", "fruit"), )
def _submit_followup_form(cls, case_id, received_on): form_id = uuid.uuid4().hex form_meta = TestFormMetadata( domain=cls.domain, xmlns=cls.followup_form.xmlns, app_id=cls.app._id, received_on=received_on, ) properties = cls._get_case_property_values() caseblock = CaseBlock( case_id=case_id, update=properties, ) form_builder = FormSubmissionBuilder( form_id=form_id, metadata=form_meta, case_blocks=[caseblock], form_properties=properties, ) submit_form_locally(form_builder.as_xml_string(), cls.domain, received_on=received_on, app_id=cls.app._id) return form_id
def _submit_followup_form(cls, case_id, received_on): form_id = uuid.uuid4().hex form_meta = TestFormMetadata( domain=cls.domain, xmlns=cls.followup_form.xmlns, app_id=cls.app._id, received_on=received_on, ) properties = cls._get_case_property_values() caseblock = CaseBlock( case_id=case_id, update=properties, ) form_builder = FormSubmissionBuilder( form_id=form_id, metadata=form_meta, case_blocks=[caseblock], form_properties=properties, ) submit_form_locally(form_builder.as_xml_string(), cls.domain, received_on=received_on, app_id=cls.app._id) return form_id
def test_update_responses(self): formxml = FormSubmissionBuilder( form_id='123', form_properties={'breakfast': 'toast', 'lunch': 'sandwich'} ).as_xml_string() xform = submit_form_locally(formxml, DOMAIN).xform updates = {'breakfast': 'fruit'} errors = FormProcessorInterface(DOMAIN).update_responses(xform, updates, 'user1') form = FormAccessors(DOMAIN).get_form(xform.form_id) self.assertEqual(0, len(errors)) self.assertEqual('fruit', form.form_data['breakfast']) self.assertEqual('sandwich', form.form_data['lunch'])
def set_up_form(cls): cls.form_id = uuid4().hex user_id = uuid4().hex cls.case_update = { 'year': '1970', 'breakfast': 'spam egg spam spam bacon spam', 'price': '2.40', 'album_release': '1972-09-08', 'breakfast_oclock': '09:00:00', 'breakfast_exactly': '1972-09-08T09:00:00.000Z', } builder = FormSubmissionBuilder( form_id=cls.form_id, form_properties={ 'name': 'spam', **cls.case_update, }, case_blocks=[ CaseBlock(case_id=uuid4().hex, create=True, case_type='sketch', case_name='spam', owner_id=user_id, update=cls.case_update) ], metadata=TestFormMetadata( domain=cls.domain, user_id=user_id, ), ) submit_form_locally(builder.as_xml_string(), cls.domain) cls.form = FormAccessors(cls.domain).get_form(cls.form_id) form_json_gen = FormRepeaterJsonPayloadGenerator(None) cls.form_json_payload_info = cls.get_payload_info(form_json_gen) form_dict_gen = FormDictPayloadGenerator(None) cls.form_dict_payload_info = cls.get_payload_info(form_dict_gen)
def test_get_readable_data_for_submission(self): formxml = FormSubmissionBuilder(form_id='123', form_properties={ 'dalmation_count': 'yes' }).as_xml_string() xform = submit_form_locally(formxml, self.domain).xform actual, _ = get_readable_data_for_submission(xform) expected = [{ 'value': '/data/dalmation_count', 'label': 'dalmation_count', 'response': 'yes' }] self.assertJSONEqual( json.dumps([q.to_json() for q in actual]), json.dumps([FormQuestionResponse(q).to_json() for q in expected]))
def test_update_responses(self): formxml = FormSubmissionBuilder( form_id='123', form_properties={ 'breakfast': 'toast', # Simple questions 'lunch': 'sandwich', 'cell': { # Simple group 'cytoplasm': 'squishy', 'organelles': 'grainy', }, 'shelves': [ # Simple repeat group {'position': 'top'}, {'position': 'middle'}, {'position': 'bottom'}, ], 'grandparent': [ # Repeat group with child group {'name': 'Haruki'}, {'name': 'Sugako'}, { 'name': 'Emma', 'parent': { 'name': 'Haruki', 'child': { 'name': 'Nao', }, } }, ], 'body': [ # Repeat group with child repeat group {'arm': [ {'elbow': '1'}, {'finger': '5'}, ]}, {'leg': [ {'knee': '1'}, {'toe': '5'}, ]}, ], } ).as_xml_string() pic = UploadedFile(BytesIO(b"fake"), 'pic.jpg', content_type='image/jpeg') xform = submit_form_locally(formxml, DOMAIN, attachments={ "image": pic }).xform updates = { 'breakfast': 'fruit', 'cell/organelles': 'bulbous', 'shelves[1]/position': 'third', 'shelves[3]/position': 'first', 'grandparent[1]/name': 'Haruki #1', 'grandparent[3]/name': 'Ema', 'grandparent[3]/parent/name': 'Haruki #2', 'grandparent[3]/parent/child/name': 'Nao-chan', 'body[1]/arm[1]/elbow': '2', 'body[2]/leg[2]/toe': '10', } errors = FormProcessorInterface(DOMAIN).update_responses( xform, updates, 'user1') form = FormAccessors(DOMAIN).get_form(xform.form_id) self.assertEqual(0, len(errors)) self.assertEqual('fruit', form.form_data['breakfast']) self.assertEqual('sandwich', form.form_data['lunch']) self.assertEqual('squishy', form.form_data['cell']['cytoplasm']) self.assertEqual('bulbous', form.form_data['cell']['organelles']) self.assertEqual('third', form.form_data['shelves'][0]['position']) self.assertEqual('middle', form.form_data['shelves'][1]['position']) self.assertEqual('first', form.form_data['shelves'][2]['position']) self.assertEqual('Haruki #1', form.form_data['grandparent'][0]['name']) self.assertEqual('Sugako', form.form_data['grandparent'][1]['name']) self.assertEqual('Ema', form.form_data['grandparent'][2]['name']) self.assertEqual('Haruki #2', form.form_data['grandparent'][2]['parent']['name']) self.assertEqual( 'Nao-chan', form.form_data['grandparent'][2]['parent']['child']['name']) self.assertEqual('2', form.form_data['body'][0]['arm'][0]['elbow']) self.assertEqual('5', form.form_data['body'][0]['arm'][1]['finger']) self.assertEqual('1', form.form_data['body'][1]['leg'][0]['knee']) self.assertEqual('10', form.form_data['body'][1]['leg'][1]['toe']) self.assertIn("image", form.attachments) self.assertEqual(form.get_attachment("image"), b"fake")
def test_get_data_cleaning_data(self, questions_patch): builder = XFormBuilder() responses = OrderedDict() # Simple question builder.new_question('something', 'Something') responses['something'] = 'blue' # Skipped question - doesn't appear in repsonses, shouldn't appear in data cleaning data builder.new_question('skip', 'Skip me') # Simple group lights = builder.new_group('lights', 'Traffic Lights', data_type='group') lights.new_question('red', 'Red means') lights.new_question('green', 'Green means') responses['lights'] = OrderedDict([('red', 'stop'), ('green', 'go')]) # Simple repeat group, one response one_hit_wonders = builder.new_group('one_hit_wonders', 'One-Hit Wonders', data_type='repeatGroup') one_hit_wonders.new_question('name', 'Name') responses['one_hit_wonders'] = [ { 'name': 'A-Ha' }, ] # Simple repeat group, multiple responses snacks = builder.new_group('snacks', 'Snacks', data_type='repeatGroup') snacks.new_question('kind_of_snack', 'Kind of snack') responses['snacks'] = [ { 'kind_of_snack': 'samosa' }, { 'kind_of_snack': 'pakora' }, ] # Repeat group with nested group cups = builder.new_group('cups_of_tea', 'Cups of tea', data_type='repeatGroup') details = cups.new_group('details_of_cup', 'Details', data_type='group') details.new_question('kind_of_cup', 'Flavor') details.new_question('secret', 'Secret', data_type=None) responses['cups_of_tea'] = [ { 'details_of_cup': { 'kind_of_cup': 'green', 'secret': 'g' } }, { 'details_of_cup': { 'kind_of_cup': 'black', 'secret': 'b' } }, { 'details_of_cup': { 'kind_of_cup': 'more green', 'secret': 'mg' } }, ] xform = XForm(builder.tostring()) questions_patch.return_value = get_questions_from_xform_node( xform, ['en']) xml = FormSubmissionBuilder(form_id='123', form_properties=responses).as_xml_string() submitted_xform = submit_form_locally(xml, self.domain).xform form_data, _ = get_readable_data_for_submission(submitted_xform) question_response_map, ordered_question_values = get_data_cleaning_data( form_data, submitted_xform) expected_question_values = [ '/data/something', '/data/lights/red', '/data/lights/green', '/data/one_hit_wonders/name', '/data/snacks[1]/kind_of_snack', '/data/snacks[2]/kind_of_snack', '/data/cups_of_tea[1]/details_of_cup/kind_of_cup', '/data/cups_of_tea[1]/details_of_cup/secret', '/data/cups_of_tea[2]/details_of_cup/kind_of_cup', '/data/cups_of_tea[2]/details_of_cup/secret', '/data/cups_of_tea[3]/details_of_cup/kind_of_cup', '/data/cups_of_tea[3]/details_of_cup/secret', ] self.assertListEqual(ordered_question_values, expected_question_values) expected_response_map = { '/data/something': 'blue', '/data/lights/red': 'stop', '/data/lights/green': 'go', '/data/one_hit_wonders/name': 'A-Ha', '/data/snacks[1]/kind_of_snack': 'samosa', '/data/snacks[2]/kind_of_snack': 'pakora', '/data/cups_of_tea[1]/details_of_cup/kind_of_cup': 'green', '/data/cups_of_tea[1]/details_of_cup/secret': 'g', '/data/cups_of_tea[2]/details_of_cup/kind_of_cup': 'black', '/data/cups_of_tea[2]/details_of_cup/secret': 'b', '/data/cups_of_tea[3]/details_of_cup/kind_of_cup': 'more green', '/data/cups_of_tea[3]/details_of_cup/secret': 'mg', } self.assertDictEqual( {k: v['value'] for k, v in question_response_map.items()}, expected_response_map)
def _submit_form(self, domain, new_cases=0, update_cases=()): case_blocks = [ CaseBlock( case_id=str(uuid.uuid4()), case_type=self.case_type, create={'name': str(uuid.uuid4())[:5]}, ) for i in range(new_cases) ] case_blocks += [ CaseBlock(case_id=case.case_id, update={}) for case in update_cases ] form_xml = FormSubmissionBuilder( form_id=str(uuid.uuid4()), case_blocks=case_blocks, metadata=TestFormMetadata(xmlns=self.form_xmlns) if self.form_xmlns else None).as_xml_string() result = submit_form_locally(form_xml, domain) return result.xform, result.cases def _send_forms_to_es(self, forms): for form in forms: es_form = transform_xform_for_elasticsearch( FormDocumentStore(form.domain, form.xmlns).get_document(form.form_id)) send_to_elasticsearch('forms', es_form) self.elasticsearch.indices.refresh(XFORM_INDEX_INFO.index) self.forms_to_delete_from_es.update(form.form_id for form in forms)