예제 #1
0
def _cached_add_inferred_export_properties(sender, domain, case_type,
                                           properties):
    from corehq.apps.export.models import MAIN_TABLE, PathNode, CaseInferredSchema, ScalarItem
    """
    Adds inferred properties to the inferred schema for a case type.

    :param: sender - The signal sender
    :param: domain
    :param: case_type
    :param: properties - An iterable of case properties to add to the inferred schema
    """

    assert domain, 'Must have domain'
    assert case_type, 'Must have case type'
    assert all(['.' not in prop
                for prop in properties]), 'Properties should not have periods'
    inferred_schema = get_case_inferred_schema(domain, case_type)
    if not inferred_schema:
        inferred_schema = CaseInferredSchema(
            domain=domain,
            case_type=case_type,
        )
    group_schema = inferred_schema.put_group_schema(MAIN_TABLE)
    add_properties_to_data_dictionary(domain, case_type, properties)

    for case_property in properties:
        path = [PathNode(name=case_property)]
        system_property_column = list(
            filter(
                lambda column: column.item.path == path and column.item.
                transform is None,
                MAIN_CASE_TABLE_PROPERTIES,
            ))

        if system_property_column:
            assert len(system_property_column) == 1
            column = system_property_column[0]
            group_schema.put_item(path,
                                  inferred_from=sender,
                                  item_cls=column.item.__class__)
        else:
            group_schema.put_item(path,
                                  inferred_from=sender,
                                  item_cls=ScalarItem)

    inferred_schema.save()
예제 #2
0
 def setUp(self):
     self.inferred_schema = CaseInferredSchema(
         domain=self.domain,
         case_type=self.case_type,
         group_schemas=[
             InferredExportGroupSchema(
                 path=MAIN_TABLE,
                 items=[
                     ExportItem(path=[
                         PathNode(name='data'),
                         PathNode(name='case_property')
                     ],
                                label='Inferred 1',
                                inferred=True),
                     ExportItem(path=[
                         PathNode(name='data'),
                         PathNode(name='case_property_2')
                     ],
                                label='Inferred 1',
                                inferred=True),
                 ],
                 inferred=True),
         ])
     self.inferred_schema.save()
예제 #3
0
 def setUp(self):
     self.inferred_schema = CaseInferredSchema(
         domain=self.domain,
         case_type=self.case_type,
         group_schemas=[
             InferredExportGroupSchema(
                 path=MAIN_TABLE,
                 items=[
                     ExportItem(
                         path=[PathNode(name='data'), PathNode(name='case_property')],
                         label='Inferred 1',
                         inferred=True
                     ),
                     ExportItem(
                         path=[PathNode(name='data'), PathNode(name='case_property_2')],
                         label='Inferred 1',
                         inferred=True
                     ),
                 ],
                 inferred=True
             ),
         ]
     )
     self.inferred_schema.save()
예제 #4
0
class TestBuildingSchemaFromApplication(TestCase, TestXmlMixin):
    file_path = ['data']
    root = os.path.dirname(__file__)
    case_type = 'wonderwoman'
    domain = 'aspace'

    @classmethod
    def setUpClass(cls):
        super(TestBuildingSchemaFromApplication, cls).setUpClass()
        cls.current_app = Application.wrap(cls.get_json('basic_application'))

        cls.first_build = Application.wrap(cls.get_json('basic_application'))
        cls.first_build._id = '123'
        cls.first_build.copy_of = cls.current_app.get_id
        cls.first_build.version = 3
        cls.first_build.has_submissions = True

        factory = AppFactory(build_version='2.36.0')
        m0, f0 = factory.new_advanced_module('mod0', 'advanced')
        f0.source = cls.get_xml('repeat_group_form').decode('utf-8')
        f0.xmlns = 'repeat-xmlns'

        factory.form_requires_case(f0, 'case0')
        f0.actions.open_cases = [
            AdvancedOpenCaseAction(
                case_type="advanced",
                case_tag="open_case_0",
                name_path="/data/question3/question4",
                repeat_context="/data/question3",
                case_indices=[CaseIndex(tag='load_case0_0')]
            )
        ]
        cls.advanced_app = factory.app
        cls.advanced_app.save()

        cls.apps = [
            cls.current_app,
            cls.first_build,
            cls.advanced_app,
        ]
        with drop_connected_signals(app_post_save):
            for app in cls.apps:
                app.save()

    @classmethod
    def tearDownClass(cls):
        for app in cls.apps:
            app.delete()
        super(TestBuildingSchemaFromApplication, cls).tearDownClass()

    def setUp(self):
        self.inferred_schema = CaseInferredSchema(
            domain=self.domain,
            case_type=self.case_type,
            group_schemas=[
                InferredExportGroupSchema(
                    path=MAIN_TABLE,
                    items=[
                        ExportItem(
                            path=[PathNode(name='data'), PathNode(name='case_property')],
                            label='Inferred 1',
                            inferred=True
                        ),
                        ExportItem(
                            path=[PathNode(name='data'), PathNode(name='case_property_2')],
                            label='Inferred 1',
                            inferred=True
                        ),
                    ],
                    inferred=True
                ),
            ]
        )
        self.inferred_schema.save()

    def tearDown(self):
        delete_all_export_data_schemas()

    def test_basic_application_schema(self):
        app = self.current_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            'my_sweet_xmlns'
        )

        self.assertEqual(len(schema.group_schemas), 1)

    @softer_assert()
    def test_process_app_failure(self):
        '''
        This ensures that the schema generated will not fail if there is an error processing one of the
        applications.
        '''
        with patch(
                'corehq.apps.export.models.new.FormExportDataSchema._process_app_build',
                side_effect=Exception('boom')):
            FormExportDataSchema.generate_schema_from_builds(
                self.current_app.domain,
                self.current_app._id,
                'my_sweet_xmlns'
            )

    def test_build_from_saved_schema(self):
        app = self.current_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            'my_sweet_xmlns'
        )

        self.assertEqual(len(schema.group_schemas), 1)
        self.assertEqual(schema.last_app_versions[app._id], self.first_build.version)

        # After the first schema has been saved let's add a second app to process
        second_build = Application.wrap(self.get_json('basic_application'))
        second_build._id = '456'
        second_build.copy_of = app.get_id
        second_build.version = 6
        second_build.has_submissions = True
        second_build.save()
        self.addCleanup(second_build.delete)

        new_schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            'my_sweet_xmlns'
        )

        self.assertEqual(new_schema._id, schema._id)
        self.assertEqual(new_schema.last_app_versions[app._id], second_build.version)
        self.assertEqual(len(new_schema.group_schemas), 1)

    def test_build_with_inferred_schema(self):
        app = self.current_app

        schema = CaseExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            self.case_type,
        )

        group_schema = schema.group_schemas[0]
        self.assertEqual(group_schema.path, MAIN_TABLE)
        self.assertTrue(group_schema.inferred)
        inferred_items = [item for item in group_schema.items if item.inferred]
        self.assertEqual(len(inferred_items), 2)

    def test_build_with_advanced_app(self):
        app = self.advanced_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            "repeat-xmlns",
        )

        group_schema = schema.group_schemas[1]  # The repeat schema
        # Assert that all proper case attributes are added to advanced forms that open
        # cases with repeats

        assertContainsExportItems(
            [
                ('form.question3.question4', 'question4'),
                ('form.question3.case.create.case_name', 'case_open_case_0.create.case_name'),
                ('form.question3.case.create.case_type', 'case_open_case_0.create.case_type'),
                ('form.question3.case.create.owner_id', 'case_open_case_0.create.owner_id'),
                ('form.question3.case.index.parent.#text', 'case_open_case_0.index.#text'),
                ('form.question3.case.index.parent.@case_type', 'case_open_case_0.index.@case_type'),
                ('form.question3.case.@case_id', 'case_open_case_0.@case_id'),
                ('form.question3.case.@date_modified', 'case_open_case_0.@date_modified'),
                ('form.question3.case.@user_id', 'case_open_case_0.@user_id'),
            ],
            group_schema
        )
        path_suffixes = set([item.path[-1].name for item in group_schema.items])
        self.assertEqual(len(path_suffixes & set(CASE_ATTRIBUTES)), len(CASE_ATTRIBUTES))
예제 #5
0
class TestBuildingSchemaFromApplication(TestCase, TestXmlMixin):
    file_path = ['data']
    root = os.path.dirname(__file__)
    case_type = 'wonderwoman'
    domain = 'aspace'

    @classmethod
    def setUpClass(cls):
        super(TestBuildingSchemaFromApplication, cls).setUpClass()
        cls.current_app = Application.wrap(cls.get_json('basic_application'))

        cls.first_build = Application.wrap(cls.get_json('basic_application'))
        cls.first_build._id = '123'
        cls.first_build.copy_of = cls.current_app.get_id
        cls.first_build.version = 3
        cls.first_build.has_submissions = True

        factory = AppFactory(build_version='2.36.0')
        m0, f0 = factory.new_advanced_module('mod0', 'advanced')
        f0.source = cls.get_xml('repeat_group_form').decode('utf-8')
        f0.xmlns = 'repeat-xmlns'

        factory.form_requires_case(f0, 'case0')
        f0.actions.open_cases = [
            AdvancedOpenCaseAction(
                case_type="advanced",
                case_tag="open_case_0",
                name_path="/data/question3/question4",
                repeat_context="/data/question3",
                case_indices=[CaseIndex(tag='load_case0_0')])
        ]
        cls.advanced_app = factory.app
        cls.advanced_app.save()

        cls.apps = [
            cls.current_app,
            cls.first_build,
            cls.advanced_app,
        ]
        with drop_connected_signals(app_post_save):
            for app in cls.apps:
                app.save()

    @classmethod
    def tearDownClass(cls):
        for app in cls.apps:
            app.delete()
        super(TestBuildingSchemaFromApplication, cls).tearDownClass()

    def setUp(self):
        self.inferred_schema = CaseInferredSchema(
            domain=self.domain,
            case_type=self.case_type,
            group_schemas=[
                InferredExportGroupSchema(
                    path=MAIN_TABLE,
                    items=[
                        ExportItem(path=[
                            PathNode(name='data'),
                            PathNode(name='case_property')
                        ],
                                   label='Inferred 1',
                                   inferred=True),
                        ExportItem(path=[
                            PathNode(name='data'),
                            PathNode(name='case_property_2')
                        ],
                                   label='Inferred 1',
                                   inferred=True),
                    ],
                    inferred=True),
            ])
        self.inferred_schema.save()

    def tearDown(self):
        delete_all_export_data_schemas()

    def test_basic_application_schema(self):
        app = self.current_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain, app._id, 'my_sweet_xmlns')

        self.assertEqual(len(schema.group_schemas), 1)

    @softer_assert()
    def test_process_app_failure(self):
        '''
        This ensures that the schema generated will not fail if there is an error processing one of the
        applications.
        '''
        with patch(
                'corehq.apps.export.models.new.FormExportDataSchema._process_app_build',
                side_effect=Exception('boom')):
            FormExportDataSchema.generate_schema_from_builds(
                self.current_app.domain, self.current_app._id,
                'my_sweet_xmlns')

    def test_build_from_saved_schema(self):
        app = self.current_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain, app._id, 'my_sweet_xmlns')

        self.assertEqual(len(schema.group_schemas), 1)
        self.assertEqual(schema.last_app_versions[app._id],
                         self.first_build.version)

        # After the first schema has been saved let's add a second app to process
        second_build = Application.wrap(self.get_json('basic_application'))
        second_build._id = '456'
        second_build.copy_of = app.get_id
        second_build.version = 6
        second_build.has_submissions = True
        second_build.save()
        self.addCleanup(second_build.delete)

        new_schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain, app._id, 'my_sweet_xmlns')

        self.assertEqual(new_schema._id, schema._id)
        self.assertEqual(new_schema.last_app_versions[app._id],
                         second_build.version)
        self.assertEqual(len(new_schema.group_schemas), 1)

    def test_build_with_inferred_schema(self):
        app = self.current_app

        schema = CaseExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            self.case_type,
        )

        group_schema = schema.group_schemas[0]
        self.assertEqual(group_schema.path, MAIN_TABLE)
        self.assertTrue(group_schema.inferred)
        inferred_items = [item for item in group_schema.items if item.inferred]
        self.assertEqual(len(inferred_items), 2)

    def test_build_with_advanced_app(self):
        app = self.advanced_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            "repeat-xmlns",
        )

        group_schema = schema.group_schemas[1]  # The repeat schema
        # Assert that all proper case attributes are added to advanced forms that open
        # cases with repeats

        assertContainsExportItems([
            ('form.question3.question4', 'question4'),
            ('form.question3.case.create.case_name',
             'case_open_case_0.create.case_name'),
            ('form.question3.case.create.case_type',
             'case_open_case_0.create.case_type'),
            ('form.question3.case.create.owner_id',
             'case_open_case_0.create.owner_id'),
            ('form.question3.case.index.parent.#text',
             'case_open_case_0.index.#text'),
            ('form.question3.case.index.parent.@case_type',
             'case_open_case_0.index.@case_type'),
            ('form.question3.case.@case_id', 'case_open_case_0.@case_id'),
            ('form.question3.case.@date_modified',
             'case_open_case_0.@date_modified'),
            ('form.question3.case.@user_id', 'case_open_case_0.@user_id'),
        ], group_schema)
        path_suffixes = set(
            [item.path[-1].name for item in group_schema.items])
        self.assertEqual(len(path_suffixes & set(CASE_ATTRIBUTES)),
                         len(CASE_ATTRIBUTES))
예제 #6
0
class TestBuildingSchemaFromApplication(TestCase, TestXmlMixin):
    file_path = ['data']
    root = os.path.dirname(__file__)
    case_type = 'wonderwoman'
    domain = 'aspace'

    @classmethod
    def setUpClass(cls):
        cls.current_app = Application.wrap(cls.get_json('basic_application'))

        cls.first_build = Application.wrap(cls.get_json('basic_application'))
        cls.first_build._id = '123'
        cls.first_build.copy_of = cls.current_app.get_id
        cls.first_build.version = 3
        cls.first_build.has_submissions = True

        cls.advanced_app = Application.new_app('domain', "Untitled Application")
        module = cls.advanced_app.add_module(AdvancedModule.new_module('Untitled Module', None))
        form = module.new_form("Untitled Form", cls.get_xml('repeat_group_form'))
        form.xmlns = 'repeat-xmlns'
        form.actions.open_cases = [
            AdvancedOpenCaseAction(
                case_type="advanced",
                case_tag="open_case_0",
                name_path="/data/question3/question4",
                repeat_context="/data/question3",
            )
        ]

        cls.apps = [
            cls.current_app,
            cls.first_build,
            cls.advanced_app,
        ]
        with drop_connected_signals(app_post_save):
            for app in cls.apps:
                app.save()

    @classmethod
    def tearDownClass(cls):
        for app in cls.apps:
            app.delete()

    def setUp(self):
        self.inferred_schema = CaseInferredSchema(
            domain=self.domain,
            case_type=self.case_type,
            group_schemas=[
                InferredExportGroupSchema(
                    path=MAIN_TABLE,
                    items=[
                        ExportItem(
                            path=[PathNode(name='data'), PathNode(name='case_property')],
                            label='Inferred 1',
                            inferred=True
                        ),
                        ExportItem(
                            path=[PathNode(name='data'), PathNode(name='case_property_2')],
                            label='Inferred 1',
                            inferred=True
                        ),
                    ],
                    inferred=True
                ),
            ]
        )
        self.inferred_schema.save()

    def tearDown(self):
        delete_all_export_data_schemas()

    def test_basic_application_schema(self):
        app = self.current_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            'my_sweet_xmlns'
        )

        self.assertEqual(len(schema.group_schemas), 1)

    @softer_assert()
    def test_process_app_failure(self):
        '''
        This ensures that the schema generated will not fail if there is an error processing one of the
        applications.
        '''
        with patch(
                'corehq.apps.export.models.new.FormExportDataSchema._process_app_build',
                side_effect=Exception('boom')):
            FormExportDataSchema.generate_schema_from_builds(
                self.current_app.domain,
                self.current_app._id,
                'my_sweet_xmlns'
            )

    def test_build_from_saved_schema(self):
        app = self.current_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            'my_sweet_xmlns'
        )

        self.assertEqual(len(schema.group_schemas), 1)
        self.assertEqual(schema.last_app_versions[app._id], self.first_build.version)

        # After the first schema has been saved let's add a second app to process
        second_build = Application.wrap(self.get_json('basic_application'))
        second_build._id = '456'
        second_build.copy_of = app.get_id
        second_build.version = 6
        second_build.has_submissions = True
        second_build.save()
        self.addCleanup(second_build.delete)

        new_schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            'my_sweet_xmlns'
        )

        self.assertEqual(new_schema._id, schema._id)
        self.assertEqual(new_schema.last_app_versions[app._id], second_build.version)
        self.assertEqual(len(new_schema.group_schemas), 1)

    def test_build_with_inferred_schema(self):
        app = self.current_app

        schema = CaseExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            self.case_type,
        )

        group_schema = schema.group_schemas[0]
        self.assertEqual(group_schema.path, MAIN_TABLE)
        self.assertTrue(group_schema.inferred)
        inferred_items = filter(lambda item: item.inferred, group_schema.items)
        self.assertEqual(len(inferred_items), 2)

    def test_build_with_advanced_app(self):
        app = self.advanced_app

        schema = FormExportDataSchema.generate_schema_from_builds(
            app.domain,
            app._id,
            "repeat-xmlns",
        )

        group_schema = schema.group_schemas[1]  # The repeat schema

        # Assert that all proper case attributes are added to advanced forms that open
        # cases with repeats
        path_suffixes = set(map(lambda item: item.path[-1].name, group_schema.items))
        self.assertEqual(len(path_suffixes & set(CASE_ATTRIBUTES)), len(CASE_ATTRIBUTES))