def test_get_ledger_values_for_case_as_of(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (self.product_a._id, 100), (self.product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # check results results = get_ledger_values_for_case_as_of( domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(2, len(results)) self.assertEqual(100, results[self.product_a._id]) self.assertEqual(50, results[self.product_b._id]) # check the date filter works before_data = datetime.utcnow() - timedelta(days=2) self.assertEqual({}, get_ledger_values_for_case_as_of( domain=self.domain, case_id=case_id, section_id='stock', as_of=before_data))
def _make_form(self, build_id=None): metadata = TestFormMetadata(domain=self.domain) form_xml = get_simple_form_xml(uuid.uuid4().hex, metadata=metadata) result = submit_form_locally(form_xml, self.domain, build_id=build_id or self.app._id) return result.xform
def test_get_ledger_values_for_case_as_of(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (self.product_a._id, 100), (self.product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # check results results = get_ledger_values_for_case_as_of(domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(2, len(results)) self.assertEqual(100, results[self.product_a._id]) self.assertEqual(50, results[self.product_b._id]) # check the date filter works before_data = datetime.utcnow() - timedelta(days=2) self.assertEqual({}, get_ledger_values_for_case_as_of(domain=self.domain, case_id=case_id, section_id='stock', as_of=before_data))
def get_form_ready_to_save(metadata, is_db_test=False): from corehq.form_processor.parsers.form import process_xform_xml from corehq.form_processor.utils import get_simple_form_xml, convert_xform_to_json from corehq.form_processor.interfaces.processor import FormProcessorInterface from corehq.form_processor.models import Attachment assert metadata is not None metadata.domain = metadata.domain or uuid.uuid4().hex form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id=form_id, metadata=metadata) if is_db_test: wrapped_form = process_xform_xml(metadata.domain, form_xml).submitted_form else: interface = FormProcessorInterface(domain=metadata.domain) form_json = convert_xform_to_json(form_xml) wrapped_form = interface.new_xform(form_json) wrapped_form.domain = metadata.domain interface.store_attachments(wrapped_form, [ Attachment( name='form.xml', raw_content=form_xml, content_type='text/xml') ]) wrapped_form.received_on = metadata.received_on wrapped_form.app_id = metadata.app_id return wrapped_form
def test_get_ledger_values_for_case_as_of_same_date(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ((self.product_a._id, 100), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # submit two transfers at the same time transfer_date = json_format_datetime(datetime.utcnow()) transfers = [ (self.product_a._id, 1, transfer_date), (self.product_a._id, 2, transfer_date), ] for prod_id, transfer, date in transfers: submit_case_blocks( get_single_transfer_block(case_id, None, prod_id, transfer, date), self.domain) # check results results = get_ledger_values_for_case_as_of(domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(1, len(results)) self.assertEqual(97, results[self.product_a._id])
def test_duplicate_form_published(self): form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id) orig_form = submit_form_locally(form_xml, domain=self.domain).xform self.assertEqual(form_id, orig_form.form_id) self.assertEqual(1, len(self.form_accessors.get_all_form_ids_in_domain())) with process_pillow_changes(self.form_pillow): with process_pillow_changes('DefaultChangeFeedPillow'): # post an exact duplicate dupe_form = submit_form_locally(form_xml, domain=self.domain).xform self.assertTrue(dupe_form.is_duplicate) self.assertNotEqual(form_id, dupe_form.form_id) if should_use_sql_backend(self.domain): self.assertEqual(form_id, dupe_form.orig_id) # make sure changes made it to kafka dupe_form_meta = self.processor.changes_seen[0].metadata self.assertEqual(dupe_form.form_id, dupe_form_meta.document_id) self.assertEqual(dupe_form.domain, dupe_form.domain) if should_use_sql_backend(self.domain): # sql domains also republish the original form to ensure that if the server crashed # in the processing of the form the first time that it is still sent to kafka orig_form_meta = self.processor.changes_seen[1].metadata self.assertEqual(orig_form.form_id, orig_form_meta.document_id) self.assertEqual(self.domain, orig_form_meta.domain) self.assertEqual(dupe_form.domain, dupe_form.domain)
def test_get_ledger_values_for_case_as_of_same_date(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (self.product_a._id, 100), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] submit_case_blocks(ledger_blocks, self.domain) # submit two transfers at the same time transfer_date = json_format_datetime(datetime.utcnow()) transfers = [ (self.product_a._id, 1, transfer_date), (self.product_a._id, 2, transfer_date), ] for prod_id, transfer, date in transfers: submit_case_blocks(get_single_transfer_block(case_id, None, prod_id, transfer, date), self.domain) # check results results = get_ledger_values_for_case_as_of( domain=self.domain, case_id=case_id, section_id='stock', as_of=datetime.utcnow()) self.assertEqual(1, len(results)) self.assertEqual(97, results[self.product_a._id])
def test_duplicate_form_published(self): form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id) orig_form = submit_form_locally(form_xml, domain=self.domain)[1] self.assertEqual(form_id, orig_form.form_id) self.assertEqual(1, len(self.form_accessors.get_all_form_ids_in_domain())) with process_kafka_changes(self.form_pillow): with process_couch_changes('DefaultChangeFeedPillow'): # post an exact duplicate dupe_form = submit_form_locally(form_xml, domain=self.domain)[1] self.assertTrue(dupe_form.is_duplicate) self.assertNotEqual(form_id, dupe_form.form_id) if should_use_sql_backend(self.domain): self.assertEqual(form_id, dupe_form.orig_id) # make sure changes made it to kafka dupe_form_meta = self.processor.changes_seen[0].metadata self.assertEqual(dupe_form.form_id, dupe_form_meta.document_id) self.assertEqual(dupe_form.domain, dupe_form.domain) if should_use_sql_backend(self.domain): # sql domains also republish the original form to ensure that if the server crashed # in the processing of the form the first time that it is still sent to kafka orig_form_meta = self.processor.changes_seen[1].metadata self.assertEqual(orig_form.form_id, orig_form_meta.document_id) self.assertEqual(self.domain, orig_form_meta.domain) self.assertEqual(dupe_form.domain, dupe_form.domain)
def test_serialize_attachments(self): form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id) form = submit_form_locally(form_xml, domain=self.domain)[1] form_xml = form.get_attachment_meta('form.xml') form_json = form.to_json(include_attachments=True) self.assertEqual(form_json['external_blobs']['form.xml']['id'], str(form_xml.attachment_id))
def test_modified_on(self): form_id = uuid.uuid4().hex before = datetime.utcnow() xml = get_simple_form_xml(form_id) submit_form_locally(xml, DOMAIN) form = self.formdb.get_form(form_id) self.assertIsNotNone(form.server_modified_on) self.assertGreater(form.server_modified_on, before)
def test_modified_on(self): form_id = uuid.uuid4().hex before = datetime.utcnow() xml = get_simple_form_xml(form_id) submit_form_locally(xml, DOMAIN) form = self.formdb.get_form(form_id) self.assertIsNotNone(form.server_modified_on) self.assertGreater(form.server_modified_on, before)
def test_serialize_attachments(self): form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id) form = submit_form_locally(form_xml, domain=self.domain).xform form_xml = form.get_attachment_meta('form.xml') form_json = form.to_json(include_attachments=True) self.assertEqual(form_json['external_blobs']['form.xml']['id'], str(form_xml.attachment_id))
def _make_form(self, build_id=None): metadata = TestFormMetadata(domain=self.domain) form_xml = get_simple_form_xml(uuid.uuid4().hex, metadata=metadata) result = submit_form_locally( form_xml, self.domain, build_id=build_id or self.app._id ) return result.xform
def create_form_for_test(domain, case_id=None, attachments=None, save=True, state=XFormInstanceSQL.NORMAL, received_on=None, user_id='user1', edited_on=None): """ Create the models directly so that these tests aren't dependent on any other apps. Not testing form processing here anyway. :param case_id: create case with ID if supplied :param attachments: additional attachments dict :param save: if False return the unsaved form :return: form object """ from corehq.form_processor.utils import get_simple_form_xml form_id = uuid4().hex utcnow = received_on or datetime.utcnow() form_xml = get_simple_form_xml(form_id, case_id) form = XFormInstanceSQL( form_id=form_id, xmlns='http://openrosa.org/formdesigner/form-processor', received_on=utcnow, user_id=user_id, domain=domain, state=state, edited_on=edited_on, ) attachments = attachments or {} attachment_tuples = [ Attachment(name=a[0], raw_content=a[1], content_type=a[1].content_type) for a in attachments.items() ] attachment_tuples.append(Attachment('form.xml', form_xml, 'text/xml')) FormProcessorSQL.store_attachments(form, attachment_tuples) cases = [] if case_id: case = CommCareCaseSQL( case_id=case_id, domain=domain, type='', owner_id=user_id, opened_on=utcnow, modified_on=utcnow, modified_by=user_id, server_modified_on=utcnow, ) case.track_create(CaseTransaction.form_transaction(case, form, utcnow)) cases = [case]
def test_previous_log_purged(self): initial_synclog_id = synclog_id_from_restore_payload( generate_restore_payload(self.project, self.restore_user, items=True)) # form submission success when there is no previous sync log form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=initial_synclog_id) # second sync synclog_id = synclog_id_from_restore_payload( generate_restore_payload(self.project, self.restore_user, restore_id=initial_synclog_id)) synclog = get_properly_wrapped_sync_log(synclog_id) self.assertEqual(synclog.previous_log_id, initial_synclog_id) self.assertFalse(synclog.previous_log_removed) # form submission after second sync should remove first synclog form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=synclog_id) synclog = get_properly_wrapped_sync_log(synclog_id) self.assertEqual(synclog.previous_log_id, initial_synclog_id) self.assertTrue(synclog.previous_log_removed) with self.assertRaises(ResourceNotFound): get_properly_wrapped_sync_log(initial_synclog_id) # form submissions after purge don't fail form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=synclog_id) # restores after purge don't fail response = generate_restore_response(self.project, self.restore_user, restore_id=synclog_id) self.assertEqual(response.status_code, 200)
def test_previous_log_purged(self): device = MockDevice(self.project, self.restore_user) initial_sync = device.sync(items=True, version=V1, app=self.app) initial_synclog_id = initial_sync.restore_id self.assertIsNone(initial_sync.get_log().previous_log_id) # form submission success when there is no previous sync log form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=initial_synclog_id) # second sync second_sync = device.sync(version=V1, app=self.app) third_sync = device.sync(version=V1, app=self.app) # form submission after second sync should remove first synclog form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) third_synclog = third_sync.get_log() # re-fetch self.assertIsNone(third_synclog.previous_log_id) with self.assertRaises(MissingSyncLog): initial_sync.get_log() with self.assertRaises(MissingSyncLog): second_sync.get_log() # form submissions after purge don't fail form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) # restores after purge don't fail fourth_sync = device.sync(version=V1, app=self.app) response = fourth_sync.config.get_response() self.assertEqual(response.status_code, 200)
def create_form_for_test(domain, case_id=None, attachments=None, save=True, state=XFormInstanceSQL.NORMAL): """ Create the models directly so that these tests aren't dependent on any other apps. Not testing form processing here anyway. :param case_id: create case with ID if supplied :param attachments: additional attachments dict :param save: if False return the unsaved form :return: form object """ from corehq.form_processor.utils import get_simple_form_xml form_id = uuid4().hex user_id = 'user1' utcnow = datetime.utcnow() form_xml = get_simple_form_xml(form_id, case_id) form = XFormInstanceSQL( form_id=form_id, xmlns='http://openrosa.org/formdesigner/form-processor', received_on=utcnow, user_id=user_id, domain=domain, state=state ) attachments = attachments or {} attachment_tuples = map( lambda a: Attachment(name=a[0], raw_content=a[1], content_type=a[1].content_type), attachments.items() ) attachment_tuples.append(Attachment('form.xml', form_xml, 'text/xml')) FormProcessorSQL.store_attachments(form, attachment_tuples) cases = [] if case_id: case = CommCareCaseSQL( case_id=case_id, domain=domain, type='', owner_id=user_id, opened_on=utcnow, modified_on=utcnow, modified_by=user_id, server_modified_on=utcnow, ) case.track_create(CaseTransaction.form_transaction(case, form)) cases = [case] if save: FormProcessorSQL.save_processed_models(ProcessedForms(form, None), cases) return form
def test_previous_log_purged(self): device = MockDevice(self.project, self.restore_user) initial_sync = device.sync(items=True, version=V1) initial_synclog_id = initial_sync.restore_id # form submission success when there is no previous sync log form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=initial_synclog_id) # second sync second_sync = device.sync(version=V1) synclog_id = second_sync.restore_id synclog = second_sync.get_log() self.assertEqual(synclog.previous_log_id, initial_synclog_id) self.assertFalse(synclog.previous_log_removed) # form submission after second sync should remove first synclog form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=synclog_id) synclog = second_sync.get_log() self.assertEqual(synclog.previous_log_id, initial_synclog_id) self.assertTrue(synclog.previous_log_removed) with self.assertRaises(ResourceNotFound): initial_sync.get_log() # form submissions after purge don't fail form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=synclog_id) # restores after purge don't fail third_sync = device.sync(version=V1) response = third_sync.config.get_response() self.assertEqual(response.status_code, 200)
def test_get_attachment_by_name(self): form = create_form_for_test(DOMAIN) form_xml = get_simple_form_xml(form.form_id) with self.assertRaises(AttachmentNotFound): FormAccessorSQL.get_attachment_by_name(form.form_id, 'not_a_form.xml') with self.assertNumQueries(1, using=db_for_read_write(XFormAttachmentSQL)): attachment_meta = FormAccessorSQL.get_attachment_by_name(form.form_id, 'form.xml') self.assertEqual(form.form_id, attachment_meta.form_id) self.assertEqual('form.xml', attachment_meta.name) self.assertEqual('text/xml', attachment_meta.content_type) self.assertEqual(form_xml, attachment_meta.read_content())
def test_get_attachment_by_name(self): form = create_form_for_test(DOMAIN) form_xml = get_simple_form_xml(form.form_id) with self.assertRaises(AttachmentNotFound): FormAccessorSQL.get_attachment_by_name(form.form_id, 'not_a_form.xml') with self.assertNumQueries(1, using=db_for_read_write(XFormAttachmentSQL)): attachment_meta = FormAccessorSQL.get_attachment_by_name(form.form_id, 'form.xml') self.assertEqual(form.form_id, attachment_meta.form_id) self.assertEqual('form.xml', attachment_meta.name) self.assertEqual('text/xml', attachment_meta.content_type) self.assertEqual(form_xml, attachment_meta.read_content())
def test_duplicate_case_published(self): case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] self.assertEqual(1, len(CaseAccessors(self.domain).get_case_ids_in_domain())) case_consumer = get_test_kafka_consumer(topics.CASE_SQL) dupe_form = submit_form_locally(form_xml, domain=self.domain)[1] self.assertTrue(dupe_form.is_duplicate) # check the case was republished case_meta = change_meta_from_kafka_message(case_consumer.next().value) self.assertEqual(case_id, case_meta.document_id) self.assertEqual(self.domain, case_meta.domain)
def test_prune_formplayer_synclogs(self): device = MockDevice(self.project, self.restore_user) device.id = 'WebAppsLogin-' + device.id first_sync = device.sync() second_sync = device.sync() third_sync = device.sync() device2 = MockDevice(self.project, self.restore_user) device2.id = 'WebAppsLogin-' + device2.id other_sync = device2.sync() form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) self.assertIsNone(third_sync.get_log().previous_log_id) with self.assertRaises(MissingSyncLog): first_sync.get_log() with self.assertRaises(MissingSyncLog): second_sync.get_log() # Other sync for same user but with different device ID is still there self.assertIsNotNone(other_sync.get_log()) # form submissions after purge don't fail form_xml = get_simple_form_xml(uuid.uuid4().hex) submit_form_locally(form_xml, self.domain, last_sync_token=third_sync.restore_id) # restores after purge don't fail fourth_sync = device.sync() response = fourth_sync.config.get_response() self.assertEqual(response.status_code, 200)
def test_modified_on_archive(self): form_id = uuid.uuid4().hex submit_form_locally(get_simple_form_xml(form_id), DOMAIN) before = datetime.utcnow() form = self.formdb.get_form(form_id) form.archive() form = self.formdb.get_form(form_id) self.assertGreater(form.server_modified_on, before) before = datetime.utcnow() form.unarchive() form = self.formdb.get_form(form_id) self.assertGreater(form.server_modified_on, before)
def test_modified_on_archive(self): form_id = uuid.uuid4().hex submit_form_locally(get_simple_form_xml(form_id), DOMAIN) before = datetime.utcnow() form = self.formdb.get_form(form_id) form.archive() form = self.formdb.get_form(form_id) self.assertGreater(form.server_modified_on, before) before = datetime.utcnow() form.unarchive() form = self.formdb.get_form(form_id) self.assertGreater(form.server_modified_on, before)
def test_get_attachment_by_name(self): form = create_form_for_test(DOMAIN) form_xml = get_simple_form_xml(form.form_id) form_db = get_db_alias_for_partitioned_doc(form.form_id) with self.assertRaises(AttachmentNotFound): FormAccessorSQL.get_attachment_by_name(form.form_id, 'not_a_form.xml') with self.assertNumQueries(1, using=form_db): attachment_meta = FormAccessorSQL.get_attachment_by_name(form.form_id, 'form.xml') self.assertEqual(form.form_id, attachment_meta.parent_id) self.assertEqual('form.xml', attachment_meta.name) self.assertEqual('text/xml', attachment_meta.content_type) with attachment_meta.open() as content: self.assertEqual(form_xml, content.read().decode('utf-8'))
def get_form_ready_to_save(metadata, is_db_test=False): from corehq.form_processor.parsers.form import process_xform_xml from corehq.form_processor.utils import get_simple_form_xml, convert_xform_to_json from corehq.form_processor.interfaces.processor import FormProcessorInterface assert metadata is not None metadata.domain = metadata.domain or uuid.uuid4().hex form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id=form_id, metadata=metadata) if is_db_test: wrapped_form = process_xform_xml(metadata.domain, form_xml).submitted_form else: form_json = convert_xform_to_json(form_xml) wrapped_form = FormProcessorInterface(domain=metadata.domain).new_xform(form_json) wrapped_form.domain = metadata.domain wrapped_form.received_on = metadata.received_on return wrapped_form
def test_get_attachment_by_name(self): form = create_form_for_test(DOMAIN) form_xml = get_simple_form_xml(form.form_id) form_db = get_db_alias_for_partitioned_doc(form.form_id) with self.assertRaises(AttachmentNotFound): FormAccessorSQL.get_attachment_by_name(form.form_id, 'not_a_form.xml') with self.assertNumQueries(1, using=form_db): attachment_meta = FormAccessorSQL.get_attachment_by_name( form.form_id, 'form.xml') self.assertEqual(form.form_id, attachment_meta.parent_id) self.assertEqual('form.xml', attachment_meta.name) self.assertEqual('text/xml', attachment_meta.content_type) with attachment_meta.open() as content: self.assertEqual(form_xml, content.read().decode('utf-8'))
def test_modified_on_delete(self): form_id = uuid.uuid4().hex submit_form_locally(get_simple_form_xml(form_id), DOMAIN) before = datetime.utcnow() form = self.formdb.get_form(form_id) form.soft_delete() form = self.formdb.get_form(form_id) self.assertTrue(form.is_deleted) self.assertGreater(form.server_modified_on, before) before = form.server_modified_on self.formdb.soft_undelete_forms([form_id]) form = self.formdb.get_form(form_id) self.assertFalse(form.is_deleted) self.assertGreater(form.server_modified_on, before)
def test_duplicate_case_published(self): # this test only runs on sql because it's handling a sql-specific edge case where duplicate # form submissions should cause cases to be resubmitted. # see: http://manage.dimagi.com/default.asp?228463 for context case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] self.assertEqual(1, len(CaseAccessors(self.domain).get_case_ids_in_domain())) with process_kafka_changes(self.case_pillow): with process_couch_changes('DefaultChangeFeedPillow'): dupe_form = submit_form_locally(form_xml, domain=self.domain)[1] self.assertTrue(dupe_form.is_duplicate) # check the case was republished self.assertEqual(1, len(self.processor.changes_seen)) case_meta = self.processor.changes_seen[0].metadata self.assertEqual(case_id, case_meta.document_id) self.assertEqual(self.domain, case_meta.domain)
def test_modified_on_delete(self): form_id = uuid.uuid4().hex submit_form_locally(get_simple_form_xml(form_id), DOMAIN) before = datetime.utcnow() form = self.formdb.get_form(form_id) form.soft_delete() form = self.formdb.get_form(form_id) self.assertTrue(form.is_deleted) self.assertGreater(form.server_modified_on, before) before = form.server_modified_on self.formdb.soft_undelete_forms([form_id]) form = self.formdb.get_form(form_id) self.assertFalse(form.is_deleted) self.assertGreater(form.server_modified_on, before)
def test_serialize_attachments(self): form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id) submit_form_locally(form_xml, domain=self.domain) form = XFormInstance.objects.get_form(form_id) with self.assertNumQueries(1, using=form.db): # 1 query to fetch the form.xml attachment. The rest are lazy form_json = form.to_json(include_attachments=True) form_xml = form.get_attachment_meta('form.xml') with self.assertNumQueries(1, using=form.db): # lazy evaluation of attachments list self.assertEqual(form_json['external_blobs']['form.xml']['id'], str(form_xml.key)) # this query goes through pl_proxy with self.assertNumQueries(1, using=form.db): # lazy evaluation of history self.assertEqual(0, len(form_json['history']))
def test_duplicate_ledger_published(self): # this test also only runs on the sql backend for reasons described in test_duplicate_case_published # setup products and case product_a = make_product(self.domain, 'A Product', 'prodcode_a') product_b = make_product(self.domain, 'B Product', 'prodcode_b') case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain) # submit ledger data balances = ( (product_a._id, 100), (product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] form = submit_case_blocks(ledger_blocks, self.domain)[0] # submit duplicate with process_pillow_changes(self.ledger_pillow): with process_pillow_changes('DefaultChangeFeedPillow'): dupe_form = submit_form_locally(form.get_xml(), domain=self.domain).xform self.assertTrue(dupe_form.is_duplicate) # confirm republished ledger_meta_a = self.processor.changes_seen[0].metadata ledger_meta_b = self.processor.changes_seen[1].metadata format_id = lambda product_id: '{}/{}/{}'.format( case_id, 'stock', product_id) expected_ids = {format_id(product_a._id), format_id(product_b._id)} for meta in [ledger_meta_a, ledger_meta_b]: self.assertTrue(meta.document_id in expected_ids) expected_ids.remove(meta.document_id) self.assertEqual(self.domain, meta.domain) # cleanup product_a.delete() product_b.delete()
def main(): attachments = { 'pic.jpg': UploadedFile(BytesIO(b"fake"), 'pic.jpg', content_type='image/jpeg', size=4) } form_id = uuid.uuid4().hex form = get_simple_form_xml(form_id) form_1 = submit_and_fetch(form, DOMAIN, attachments) self.assertTrue(not form_1.is_duplicate) check_attachments(form_1, attachments) form_2 = submit_and_fetch(form, DOMAIN, attachments) form_1 = self.formdb.get_form(form_id) self.assertTrue(not form_1.is_duplicate) self.assertTrue(form_2.is_duplicate) check_attachments(form_1, attachments) check_attachments(form_2, attachments)
def test_duplicate_case_published(self): # this test only runs on sql because it's handling a sql-specific edge case where duplicate # form submissions should cause cases to be resubmitted. # see: http://manage.dimagi.com/default.asp?228463 for context case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain) self.assertEqual( 1, len(CaseAccessors(self.domain).get_case_ids_in_domain())) with process_pillow_changes(self.case_pillow): with process_pillow_changes('DefaultChangeFeedPillow'): dupe_form = submit_form_locally(form_xml, domain=self.domain).xform self.assertTrue(dupe_form.is_duplicate) # check the case was republished self.assertEqual(1, len(self.processor.changes_seen)) case_meta = self.processor.changes_seen[0].metadata self.assertEqual(case_id, case_meta.document_id) self.assertEqual(self.domain, case_meta.domain)
def test_duplicate_ledger_published(self): # this test also only runs on the sql backend for reasons described in test_duplicate_case_published # setup products and case product_a = make_product(self.domain, 'A Product', 'prodcode_a') product_b = make_product(self.domain, 'B Product', 'prodcode_b') case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (product_a._id, 100), (product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] form = submit_case_blocks(ledger_blocks, self.domain)[0] # submit duplicate with process_kafka_changes(self.ledger_pillow): with process_couch_changes('DefaultChangeFeedPillow'): dupe_form = submit_form_locally(form.get_xml(), domain=self.domain)[1] self.assertTrue(dupe_form.is_duplicate) # confirm republished ledger_meta_a = self.processor.changes_seen[0].metadata ledger_meta_b = self.processor.changes_seen[1].metadata format_id = lambda product_id: '{}/{}/{}'.format(case_id, 'stock', product_id) expected_ids = {format_id(product_a._id), format_id(product_b._id)} for meta in [ledger_meta_a, ledger_meta_b]: self.assertTrue(meta.document_id in expected_ids) expected_ids.remove(meta.document_id) self.assertEqual(self.domain, meta.domain) # cleanup product_a.delete() product_b.delete()
def test_duplicate_form_published(self): form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id) orig_form = submit_form_locally(form_xml, domain=self.domain)[1] self.assertEqual(form_id, orig_form.form_id) self.assertEqual(1, len(self.form_accessors.get_all_form_ids_in_domain())) form_consumer = get_test_kafka_consumer(topics.FORM_SQL) # post an exact duplicate dupe_form = submit_form_locally(form_xml, domain=self.domain)[1] self.assertTrue(dupe_form.is_duplicate) self.assertNotEqual(form_id, dupe_form.form_id) self.assertEqual(form_id, dupe_form.orig_id) # make sure changes made it to kafka # first the dupe dupe_form_meta = change_meta_from_kafka_message(form_consumer.next().value) self.assertEqual(dupe_form.form_id, dupe_form_meta.document_id) # then the original form orig_form_meta = change_meta_from_kafka_message(form_consumer.next().value) self.assertEqual(orig_form.form_id, orig_form_meta.document_id) self.assertEqual(self.domain, orig_form_meta.domain)
def test_duplicate_ledger_published(self): # setup products and case product_a = make_product(self.domain, 'A Product', 'prodcode_a') product_b = make_product(self.domain, 'B Product', 'prodcode_b') case_id = uuid.uuid4().hex form_xml = get_simple_form_xml(uuid.uuid4().hex, case_id) submit_form_locally(form_xml, domain=self.domain)[1] # submit ledger data balances = ( (product_a._id, 100), (product_b._id, 50), ) ledger_blocks = [ get_single_balance_block(case_id, prod_id, balance) for prod_id, balance in balances ] form = submit_case_blocks(ledger_blocks, self.domain) # submit duplicate ledger_consumer = get_test_kafka_consumer(topics.LEDGER) dupe_form = submit_form_locally(form.get_xml(), domain=self.domain)[1] self.assertTrue(dupe_form.is_duplicate) # confirm republished ledger_meta_a = change_meta_from_kafka_message(ledger_consumer.next().value) ledger_meta_b = change_meta_from_kafka_message(ledger_consumer.next().value) format_id = lambda product_id: '{}/{}/{}'.format(case_id, 'stock', product_id) expected_ids = {format_id(product_a._id), format_id(product_b._id)} for meta in [ledger_meta_a, ledger_meta_b]: self.assertTrue(meta.document_id in expected_ids) expected_ids.remove(meta.document_id) self.assertEqual(self.domain, meta.domain) # cleanup product_a.delete() product_b.delete()
def get_form_ready_to_save(metadata, is_db_test=False): from corehq.form_processor.parsers.form import process_xform_xml from corehq.form_processor.utils import get_simple_form_xml, convert_xform_to_json from corehq.form_processor.interfaces.processor import FormProcessorInterface from corehq.form_processor.models import Attachment assert metadata is not None metadata.domain = metadata.domain or uuid.uuid4().hex form_id = uuid.uuid4().hex form_xml = get_simple_form_xml(form_id=form_id, metadata=metadata) if is_db_test: wrapped_form = process_xform_xml(metadata.domain, form_xml).submitted_form else: interface = FormProcessorInterface(domain=metadata.domain) form_json = convert_xform_to_json(form_xml) wrapped_form = interface.new_xform(form_json) wrapped_form.domain = metadata.domain interface.store_attachments(wrapped_form, [ Attachment(name='form.xml', raw_content=form_xml, content_type='text/xml') ]) wrapped_form.received_on = metadata.received_on wrapped_form.app_id = metadata.app_id return wrapped_form