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))
Esempio n. 2
0
 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))
Esempio n. 4
0
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])
Esempio n. 6
0
    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])
Esempio n. 8
0
    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)
Esempio n. 9
0
    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))
Esempio n. 10
0
 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)
Esempio n. 11
0
 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))
Esempio n. 13
0
 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
Esempio n. 14
0
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]
Esempio n. 15
0
    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)
Esempio n. 16
0
    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)
Esempio n. 17
0
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
Esempio n. 18
0
    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)
Esempio n. 19
0
    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())
Esempio n. 20
0
    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())
Esempio n. 21
0
    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)
Esempio n. 22
0
    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)
Esempio n. 23
0
    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)
Esempio n. 24
0
    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)
Esempio n. 25
0
    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'))
Esempio n. 26
0
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
Esempio n. 27
0
    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'))
Esempio n. 28
0
    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)
Esempio n. 29
0
    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)
Esempio n. 30
0
    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)
Esempio n. 31
0
    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']))
Esempio n. 32
0
    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()
Esempio n. 33
0
        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)
Esempio n. 34
0
    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)
Esempio n. 35
0
    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()
Esempio n. 36
0
    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)
Esempio n. 37
0
    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()
Esempio n. 38
0
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