Пример #1
0
    def test_expand_column_infos(self):

        aggregated_report = ReportConfiguration(
            domain=self.domain.name,
            config_id=self.data_source._id,
            aggregation_columns=["opened_by"],
            columns=[
                {
                    "column_id": self.field_name,
                    "type": "field",
                    "field": self.field_name,
                    "aggregation": "expand",
                }
            ],
            filters=[],
        )
        aggregated_report.save()

        response = self.client.get(
            self.single_endpoint(aggregated_report._id))
        response_dict = json.loads(response.content)
        columns = response_dict["columns"]

        for c in columns:
            self.assertIn("expand_column_value", c)
        self.assertSetEqual(set(self.case_property_values), {c['expand_column_value'] for c in columns})
Пример #2
0
 def _create_report(cls):
     report_config = ReportConfiguration(
         domain=cls.domain,
         config_id=cls.data_sources[UCR_SQL_BACKEND]._id,
         title='foo',
         filters=[{
             "type": "date",
             "field": "date_as_date",
             "slug": "date_as_date_filter",
             "display": "Date as Date filter"
         }, {
             "type": "date",
             "field": "date_as_string",
             "slug": "date_as_string_filter",
             "display": "Date as String filter",
             "compare_as_string": True,
         }, {
             "type": "date",
             "field": "datetime_as_datetime",
             "slug": "datetime_as_datetime_filter",
             "display": "Datetime as Datetime filter",
             "compare_as_string": False,
         }],
         aggregation_columns=['doc_id'],
         columns=[{
             # We don't really care what columns are returned, we're testing the filters
             "type": "field",
             "display": "doc_id",
             "field": 'doc_id',
             'column_id': 'doc_id',
             'aggregation': 'simple'
         }],
     )
     report_config.save()
     return report_config
Пример #3
0
    def create_report(self):
        """
        Creates data source and report config.
        """
        matching_data_source = self.ds_builder.get_existing_match()
        if matching_data_source:
            data_source_config_id = matching_data_source['id']
        else:
            data_source_config_id = self._build_data_source()

        report = ReportConfiguration(
            domain=self.domain,
            config_id=data_source_config_id,
            title=self.report_name,
            aggregation_columns=self._report_aggregation_cols,
            columns=self._report_columns,
            filters=self._report_filters,
            configured_charts=self._report_charts,
            report_meta=ReportMeta(
                created_by_builder=True,
                builder_report_type=self.report_type
            )
        )
        report.validate()
        report.save()
        return report
Пример #4
0
    def test_expand_column_infos(self):

        aggregated_report = ReportConfiguration(
            domain=self.domain.name,
            config_id=self.data_source._id,
            aggregation_columns=["opened_by"],
            columns=[{
                "column_id": self.field_name,
                "type": "field",
                "field": self.field_name,
                "aggregation": "expand",
            }],
            filters=[],
        )
        aggregated_report.save()

        response = self.client.get(self.single_endpoint(aggregated_report._id))
        response_dict = json.loads(response.content)
        columns = response_dict["columns"]

        for c in columns:
            self.assertIn("expand_column_value", c)
        self.assertSetEqual(set(self.case_property_values),
                            {c['expand_column_value']
                             for c in columns})
Пример #5
0
    def setUpClass(cls):
        super(TestSimpleReportConfigurationResource, cls).setUpClass()

        cls.report_columns = [{
            "column_id": 'foo',
            "display": "foo display",
            "type": "field",
            "field": "my_field",
            "aggregation": "simple",
        }, {
            "column_id": 'bar',
            "display": "bar display",
            "type": "field",
            "field": "my_field",
            "aggregation": "simple",
        }, {
            "column_id": 'expand',
            "display": "expand display",
            "type": "expanded",
            "field": "my_field",
            "max_expansion": 10,
        }]
        cls.report_filters = [{
            'datatype': 'integer',
            'field': 'my_field',
            'type': 'dynamic_choice_list',
            'slug': 'my_field_filter',
        }, {
            'datatype': 'string',
            'field': 'my_other_field',
            'type': 'dynamic_choice_list',
            'slug': 'my_other_field_filter',
        }]
        cls.report_title = "test report"

        cls.data_source = DataSourceConfiguration(
            domain=cls.domain.name,
            referenced_doc_type="XFormInstance",
            table_id=uuid.uuid4().hex,
        )
        cls.data_source.save()

        cls.report_configuration = ReportConfiguration(
            title=cls.report_title,
            domain=cls.domain.name,
            config_id=cls.data_source._id,
            columns=cls.report_columns,
            filters=cls.report_filters)
        cls.report_configuration.save()

        another_report_configuration = ReportConfiguration(
            domain=cls.domain.name,
            config_id=cls.data_source._id,
            columns=[],
            filters=[])
        another_report_configuration.save()
 def _create_report(self, aggregation_columns, columns):
     report_config = ReportConfiguration(
         domain=self.domain,
         config_id=self.data_source_config._id,
         title="foo",
         aggregation_columns=aggregation_columns,
         columns=columns,
     )
     report_config.save()
     return report_config
 def _create_report(self, aggregation_columns, columns):
     report_config = ReportConfiguration(
         domain=self.domain,
         config_id=self.data_source_config._id,
         title='foo',
         aggregation_columns=aggregation_columns,
         columns=columns,
     )
     report_config.save()
     return report_config
Пример #8
0
    def _build_report(self, vals, field="my_field", build_data_source=True):
        """
        Build a new report, and populate it with cases.

        Return a ConfigurableReportDataSource and a FieldColumn
        :param vals: List of values to populate the given report field with.
        :param field: The name of a field in the data source/report
        :return: Tuple containing a ConfigurableReportDataSource and FieldColumn.
        The column is a column mapped to the given field.
        """

        # Create Cases
        for v in vals:
            self._new_case({field: v}).save()

        # Create report
        data_source_config = DataSourceConfiguration(
            domain=self.domain,
            display_name="foo",
            referenced_doc_type="CommCareCase",
            table_id=_clean_table_name(self.domain, str(uuid.uuid4().hex)),
            configured_filter={
                "type": "boolean_expression",
                "operator": "eq",
                "expression": {"type": "property_name", "property_name": "type"},
                "property_value": self.case_type,
            },
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {"type": "property_name", "property_name": field},
                    "column_id": field,
                    "display_name": field,
                    "datatype": "string",
                }
            ],
        )
        data_source_config.validate()
        data_source_config.save()
        if build_data_source:
            tasks.rebuild_indicators(data_source_config._id)

        report_config = ReportConfiguration(
            domain=self.domain,
            config_id=data_source_config._id,
            title="foo",
            aggregation_columns=["doc_id"],
            columns=[{"type": "expanded", "field": field, "display": field, "format": "default"}],
            filters=[],
            configured_charts=[],
        )
        report_config.save()
        data_source = ReportFactory.from_spec(report_config)

        return data_source, data_source.column_configs[0]
    def test_unlink_ucr_returns_none_if_not_linked(self):
        report = ReportConfiguration()
        report.domain = self.domain
        report.config_id = '123abd'
        report.report_meta = ReportMeta()
        report.save()
        self.addCleanup(report.delete)

        unlinked_report = unlink_report(report)

        self.assertIsNone(unlinked_report)
Пример #10
0
 def _create_report(self, aggregation_columns, columns):
     backend_id = settings.OVERRIDE_UCR_BACKEND or UCR_SQL_BACKEND
     report_config = ReportConfiguration(
         domain=self.domain,
         config_id=self.data_sources[backend_id]._id,
         title='foo',
         aggregation_columns=aggregation_columns,
         columns=columns,
     )
     report_config.save()
     return report_config
Пример #11
0
 def _create_report(self, aggregation_columns, columns):
     backend_id = settings.OVERRIDE_UCR_BACKEND or UCR_SQL_BACKEND
     report_config = ReportConfiguration(
         domain=self.domain,
         config_id=self.data_sources[backend_id]._id,
         title='foo',
         aggregation_columns=aggregation_columns,
         columns=columns,
     )
     report_config.save()
     return report_config
Пример #12
0
 def _create_report(self, aggregation_columns, columns, filters=None):
     report_config = ReportConfiguration(
         domain=self.domain,
         config_id=self.data_source._id,
         title='foo',
         aggregation_columns=aggregation_columns,
         columns=columns,
         filters=filters or [],
     )
     report_config.save()
     return report_config
Пример #13
0
 def _create_report(self, aggregation_columns, columns, sort_expression=None):
     report_config = ReportConfiguration(
         domain=self.domain,
         config_id=self.data_source._id,
         title='foo',
         aggregation_columns=aggregation_columns,
         columns=columns,
     )
     if sort_expression:
         report_config.sort_expression = sort_expression
     report_config.save()
     return report_config
Пример #14
0
 def _create_report(self, aggregation_columns, columns, sort_expression=None):
     report_config = ReportConfiguration(
         domain=self.domain,
         config_id=self.data_source._id,
         title='foo',
         aggregation_columns=aggregation_columns,
         columns=columns,
     )
     if sort_expression:
         report_config.sort_expression = sort_expression
     report_config.save()
     return report_config
Пример #15
0
    def test_updating_report_that_shares_data_source(self):
        """
        If a report builder builder report shares a data source with another report,
        then editing the report builder report should result in a new data source
        being created for the report.
        """

        # Make report
        builder_form = ConfigureListReportForm(
            self.domain,
            "Test Report",
            self.app._id,
            "form",
            self.form.unique_id,
            existing_report=None,
            data={
                'user_filters':
                '[]',
                'default_filters':
                '[]',
                'columns':
                '[{"property": "/data/first_name", "display_text": "first name", "calculation":"Group By"}]',
            })
        self.assertTrue(builder_form.is_valid())
        report = builder_form.create_report()

        # Make another report that references the same data source
        report_two = ReportConfiguration(domain="domain",
                                         config_id=report.config_id)
        report_two.save()

        # Make an edit to the first report builder report
        builder_form = ConfigureListReportForm(
            self.domain,
            "Test Report",
            self.app._id,
            "form",
            self.form.unique_id,
            existing_report=report,
            data={
                'user_filters':
                '[]',
                'default_filters':
                '[]',
                'columns':
                '[{"property": "/data/first_name", "display_text": "first name", "calculation": "Group By"}]',
            })
        self.assertTrue(builder_form.is_valid())
        report = builder_form.update_report()

        self.assertNotEqual(report.config_id, report_two.config_id)
Пример #16
0
    def _create_report(self, master_id=None):
        data_source = get_sample_data_source()
        data_source.domain = self.domain
        data_source.save()
        self.addCleanup(data_source.delete)

        report = ReportConfiguration()
        report.config_id = data_source.get_id
        report.domain = self.domain
        report.report_meta = ReportMeta()
        report.report_meta.master_id = master_id
        report.save()
        self.addCleanup(report.delete)
        return report
Пример #17
0
    def test_updating_report_that_shares_data_source(self):
        """
        If a report builder builder report shares a data source with another report,
        then editing the report builder report should result in a new data source
        being created for the report.
        """

        # Make report
        builder_form = ConfigureListReportForm(
            "Test Report",
            self.app._id,
            "form",
            self.form.unique_id,
            existing_report=None,
            data={
                'user_filters': '[]',
                'default_filters': '[]',
                'columns': '[{"property": "/data/first_name", "display_text": "first name"}]',
            }
        )
        self.assertTrue(builder_form.is_valid())
        report = builder_form.create_report()

        # Make another report that references the same data source
        report_two = ReportConfiguration(
            domain="domain",
            config_id=report.config_id
        )
        report_two.save()

        # Make an edit to the first report builder report
        builder_form = ConfigureListReportForm(
            "Test Report",
            self.app._id,
            "form",
            self.form.unique_id,
            existing_report=report,
            data={
                'user_filters': '[]',
                'default_filters': '[]',
                'columns': '[{"property": "/data/first_name", "display_text": "first name"}]',
            }
        )
        self.assertTrue(builder_form.is_valid())
        report = builder_form.update_report()

        self.assertNotEqual(report.config_id, report_two.config_id)
Пример #18
0
def _create_report(domain, title="report", upstream_id=None, should_save=True):
    data_source = DataSourceConfiguration(
        domain=domain,
        table_id=uuid.uuid4().hex,
        referenced_doc_type='XFormInstance',
    )
    data_source.save()
    report = ReportConfiguration(
        domain=domain,
        config_id=data_source._id,
        title=title,
        report_meta=ReportMeta(created_by_builder=True, master_id=upstream_id),
    )
    if should_save:
        report.save()

    return report
Пример #19
0
    def create_report(self):
        """
        Creates data source and report config.
        """
        matching_data_source = self.ds_builder.get_existing_match()
        if matching_data_source:
            data_source_config_id = matching_data_source['id']
        else:
            data_source_config = DataSourceConfiguration(
                domain=self.domain,
                display_name=self.ds_builder.data_source_name,
                referenced_doc_type=self.ds_builder.source_doc_type,
                # The uuid gets truncated, so it's not really universally unique.
                table_id=_clean_table_name(self.domain, str(uuid.uuid4().hex)),
                configured_filter=self.ds_builder.filter,
                configured_indicators=self.ds_builder.indicators,
                meta=DataSourceMeta(build=DataSourceBuildInformation(
                    source_id=self.report_source_id,
                    app_id=self.app._id,
                    app_version=self.app.version,
                ))
            )
            data_source_config.validate()
            data_source_config.save()
            tasks.rebuild_indicators.delay(data_source_config._id)
            data_source_config_id = data_source_config._id

        report = ReportConfiguration(
            domain=self.domain,
            config_id=data_source_config_id,
            title=self.report_name,
            aggregation_columns=self._report_aggregation_cols,
            columns=self._report_columns,
            filters=self._report_filters,
            configured_charts=self._report_charts,
            report_meta=ReportMeta(
                created_by_builder=True,
                builder_report_type=self.report_type
            )
        )
        report.validate()
        report.save()
        return report
Пример #20
0
    def _build_report(self, vals, field='my_field', build_data_source=True):
        """
        Build a new report, and populate it with cases.

        Return a ConfigurableReportDataSource and a FieldColumn
        :param vals: List of values to populate the given report field with.
        :param field: The name of a field in the data source/report
        :return: Tuple containing a ConfigurableReportDataSource and FieldColumn.
        The column is a column mapped to the given field.
        """

        # Create Cases
        for v in vals:
            update_props = {field: v} if v is not None else {}
            self._new_case(update_props).save()

        if build_data_source:
            tasks.rebuild_indicators(self.data_source_config._id)
            adapter = get_indicator_adapter(self.data_source_config)
            adapter.refresh_table()

        report_config = ReportConfiguration(
            domain=self.domain,
            config_id=self.data_source_config._id,
            title='foo',
            aggregation_columns=['doc_id'],
            columns=[{
                "type": "expanded",
                "field": field,
                "display": field,
                "format": "default",
            }],
            filters=[],
            configured_charts=[]
        )
        report_config.save()
        self.addCleanup(report_config.delete)
        data_source = ConfigurableReportDataSource.from_spec(report_config)

        return data_source, data_source.top_level_columns[0]
Пример #21
0
 def _create_report(cls):
     report_config = ReportConfiguration(
         domain=cls.domain,
         config_id=cls.data_sources[UCR_SQL_BACKEND]._id,
         title='foo',
         filters=[
             {
                 "type": "date",
                 "field": "date_as_date",
                 "slug": "date_as_date_filter",
                 "display": "Date as Date filter"
             },
             {
                 "type": "date",
                 "field": "date_as_string",
                 "slug": "date_as_string_filter",
                 "display": "Date as String filter",
                 "compare_as_string": True,
             },
             {
                 "type": "date",
                 "field": "datetime_as_datetime",
                 "slug": "datetime_as_datetime_filter",
                 "display": "Datetime as Datetime filter",
                 "compare_as_string": False,
             }
         ],
         aggregation_columns=['doc_id'],
         columns=[{
             # We don't really care what columns are returned, we're testing the filters
             "type": "field",
             "display": "doc_id",
             "field": 'doc_id',
             'column_id': 'doc_id',
             'aggregation': 'simple'
         }],
     )
     report_config.save()
     return report_config
Пример #22
0
    def _build_report(self, vals, field='my_field', build_data_source=True):
        """
        Build a new report, and populate it with cases.

        Return a ConfigurableReportDataSource and a FieldColumn
        :param vals: List of values to populate the given report field with.
        :param field: The name of a field in the data source/report
        :return: Tuple containing a ConfigurableReportDataSource and FieldColumn.
        The column is a column mapped to the given field.
        """

        # Create Cases
        for v in vals:
            update_props = {field: v} if v is not None else {}
            self._new_case(update_props).save()

        if build_data_source:
            tasks.rebuild_indicators(self.data_source_config._id)

        report_config = ReportConfiguration(
            domain=self.domain,
            config_id=self.data_source_config._id,
            title='foo',
            aggregation_columns=['doc_id'],
            columns=[{
                "type": "expanded",
                "field": field,
                "display": field,
                "format": "default",
            }],
            filters=[],
            configured_charts=[]
        )
        report_config.save()
        self.addCleanup(report_config.delete)
        data_source = ConfigurableReportDataSource.from_spec(report_config)

        return data_source, data_source.top_level_columns[0]
Пример #23
0
    def create_report(self):
        """
        Creates data source and report config.
        """
        matching_data_source = self.ds_builder.get_existing_match()
        if matching_data_source:
            data_source_config_id = matching_data_source._id
            reactivated = False
            if matching_data_source.is_deactivated:
                matching_data_source.is_deactivated = False
                reactivated = True
            changed = False
            indicators = self.ds_builder.indicators(self._number_columns)
            if matching_data_source.configured_indicators != indicators:
                matching_data_source.configured_indicators = indicators
                changed = True
            if changed or reactivated:
                matching_data_source.save()
                tasks.rebuild_indicators.delay(matching_data_source._id)
        else:
            data_source_config_id = self._build_data_source()

        report = ReportConfiguration(
            domain=self.domain,
            config_id=data_source_config_id,
            title=self.report_name,
            aggregation_columns=self._report_aggregation_cols,
            columns=self._report_columns,
            filters=self._report_filters,
            configured_charts=self._report_charts,
            report_meta=ReportMeta(
                created_by_builder=True,
                builder_report_type=self.report_type
            )
        )
        report.validate()
        report.save()
        return report
Пример #24
0
    def create_report(self):
        """
        Creates data source and report config.
        """
        matching_data_source = self.ds_builder.get_existing_match()
        if matching_data_source:
            data_source_config_id = matching_data_source['id']
        else:
            data_source_config_id = self._build_data_source()

        report = ReportConfiguration(
            domain=self.domain,
            config_id=data_source_config_id,
            title=self.report_name,
            aggregation_columns=self._report_aggregation_cols,
            columns=self._report_columns,
            filters=self._report_filters,
            configured_charts=self._report_charts,
            report_meta=ReportMeta(created_by_builder=True,
                                   builder_report_type=self.report_type))
        report.validate()
        report.save()
        return report
Пример #25
0
class ReportDataTest(TestCase):

    def setUp(self):
        super(ReportDataTest, self).setUp()
        # Create report
        self.domain = 'test-ucr-report-data'
        self.data_source = DataSourceConfiguration(
            domain=self.domain,
            referenced_doc_type='CommCareCase',
            table_id=uuid.uuid4().hex,
            configured_filter={},
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'name'
                    },
                    "column_id": 'name',
                    "display_name": 'name',
                    "datatype": "string"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'number'
                    },
                    "column_id": 'number',
                    "display_name": 'number',
                    "datatype": "integer"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'number'
                    },
                    "column_id": 'string-number',
                    "display_name": 'string-number',
                    "datatype": "string"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'just_for_sorting'
                    },
                    "column_id": 'just_for_sorting',
                    "display_name": 'just_for_sorting',
                    "datatype": "string"
                }
            ],
        )
        self.data_source.validate()
        self.data_source.save()
        self.adapter = get_indicator_adapter(self.data_source)
        self.adapter.rebuild_table()
        self.addCleanup(self.data_source.delete)

        # initialize a report on the data
        self.report_config = ReportConfiguration(
            domain=self.domain,
            config_id=self.data_source._id,
            aggregation_columns=['doc_id'],
            columns=[
                {
                    "type": "field",
                    "field": "name",
                    "column_id": "name",
                    "display": "Name",
                    "aggregation": "simple",
                },
                {
                    "type": "field",
                    "field": "number",
                    "column_id": "number",
                    "display": "Number",
                    "aggregation": "simple",
                    "calculate_total": True,
                },
                {
                    "type": "expression",
                    "column_id": "ten",
                    "display": "The Number Ten",
                    "expression": {
                        'type': 'constant',
                        'constant': 10,
                    }
                },
                {
                    "type": "expression",
                    "column_id": "by_tens",
                    "display": "Counting by tens",
                    "expression": {
                        "type": "evaluator",
                        "statement": "a * b",
                        "context_variables": {
                            "a": {
                                "type": "property_name",
                                "property_name": "number",
                            },
                            "b": {
                                "type": "property_name",
                                "property_name": "ten",
                            }
                        }
                    }
                },
                {
                    "type": "field",
                    "field": 'string-number',
                    "display": 'Display Number',
                    "aggregation": "simple",
                    "transform": {
                        "type": "translation",
                        "translations": {
                            "0": "zero",
                            "1": {"en": "one", "es": "uno"},
                            "2": {"en": "two", "es": "dos"}
                        },
                    },
                }
            ],
            filters=[],
            configured_charts=[],
            sort_expression=[{'field': 'just_for_sorting', 'order': 'DESC'}]
        )
        self.report_config.save()
        self.addCleanup(self.report_config.delete)

    def _add_some_rows(self, count):
        rows = [ReportDataTestRow(uuid.uuid4().hex, i, i) for i in range(count)]
        self._add_rows(rows)
        return rows

    def _add_rows(self, rows):
        pillow = get_case_pillow(ucr_configs=[self.data_source])

        def _get_case(row):
            return {
                '_id': uuid.uuid4().hex,
                'domain': self.domain,
                'doc_type': 'CommCareCase',
                'type': 'city',
                'name': row.name,
                'number': row.number,
                'just_for_sorting': row.sort_key,
            }
        for row in rows:
            pillow.process_change(doc_to_change(_get_case(row)))

    def test_basic_query(self):
        # add a few rows to the data source
        rows = self._add_some_rows(3)

        # check the returned data from the report looks right
        report_data_source = ConfigurableReportDataSource.from_spec(self.report_config)
        report_data = report_data_source.get_data()
        self.assertEqual(len(rows), len(report_data))
        rows_by_name = {r.name: r for r in rows}
        for row in report_data:
            self.assertTrue(row['name'] in rows_by_name)
            self.assertEqual(rows_by_name[row['name']].number, row['number'])
            self.assertEqual(10, row['ten'])
            self.assertEqual(10 * row['number'], row['by_tens'])

    def test_limit(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ConfigurableReportDataSource.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        limited_data = report_data_source.get_data(limit=3)
        self.assertEqual(3, len(limited_data))
        self.assertEqual(original_data[:3], limited_data)

    def test_skip(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ConfigurableReportDataSource.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        skipped = report_data_source.get_data(start=3)
        self.assertEqual(count - 3, len(skipped))
        self.assertEqual(original_data[3:], skipped)

    def test_total_row(self):
        rows = self._add_some_rows(3)
        report_data_source = ConfigurableReportDataSource.from_spec(self.report_config)

        total_number = sum(row.number for row in rows)
        self.assertEqual(report_data_source.get_total_row(), ['Total', total_number, '', '', ''])

    def test_transform(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ConfigurableReportDataSource.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        rows_by_number = {int(row['number']): row for row in original_data}
        # Make sure the translations happened
        self.assertEqual(rows_by_number[0]['string-number'], "zero")
        self.assertEqual(rows_by_number[1]['string-number'], "one")
        self.assertEqual(rows_by_number[2]['string-number'], "two")
        # These last two are untranslated
        self.assertEqual(rows_by_number[3]['string-number'], "3")
        self.assertEqual(rows_by_number[4]['string-number'], "4")
Пример #26
0
class ReportDataTest(TestCase):
    def setUp(self):
        super(ReportDataTest, self).setUp()
        # Create report
        self.domain = 'test-ucr-report-data'
        self.data_source = DataSourceConfiguration(
            domain=self.domain,
            referenced_doc_type='CommCareCase',
            table_id=uuid.uuid4().hex,
            configured_filter={},
            configured_indicators=[{
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": 'name'
                },
                "column_id": 'name',
                "display_name": 'name',
                "datatype": "string"
            }, {
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": 'number'
                },
                "column_id": 'number',
                "display_name": 'number',
                "datatype": "integer"
            }, {
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": 'number'
                },
                "column_id": 'string-number',
                "display_name": 'string-number',
                "datatype": "string"
            }, {
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": 'just_for_sorting'
                },
                "column_id": 'just_for_sorting',
                "display_name": 'just_for_sorting',
                "datatype": "string"
            }],
        )
        self.data_source.validate()
        self.data_source.save()
        self.adapter = get_indicator_adapter(self.data_source)
        self.adapter.rebuild_table()
        self.addCleanup(self.data_source.delete)

        # initialize a report on the data
        self.report_config = ReportConfiguration(
            domain=self.domain,
            config_id=self.data_source._id,
            aggregation_columns=['doc_id'],
            columns=[{
                "type": "field",
                "field": "name",
                "column_id": "name",
                "display": "Name",
                "aggregation": "simple",
            }, {
                "type": "field",
                "field": "number",
                "column_id": "number",
                "display": "Number",
                "aggregation": "simple",
                "calculate_total": True,
            }, {
                "type": "expression",
                "column_id": "ten",
                "display": "The Number Ten",
                "expression": {
                    'type': 'constant',
                    'constant': 10,
                }
            }, {
                "type": "expression",
                "column_id": "by_tens",
                "display": "Counting by tens",
                "expression": {
                    "type": "evaluator",
                    "statement": "a * b",
                    "context_variables": {
                        "a": {
                            "type": "property_name",
                            "property_name": "number",
                        },
                        "b": {
                            "type": "property_name",
                            "property_name": "ten",
                        }
                    }
                }
            }, {
                "type": "field",
                "field": 'string-number',
                "display": 'Display Number',
                "aggregation": "simple",
                "transform": {
                    "type": "translation",
                    "translations": {
                        "0": "zero",
                        "1": {
                            "en": "one",
                            "es": "uno"
                        },
                        "2": {
                            "en": "two",
                            "es": "dos"
                        }
                    },
                },
            }],
            filters=[],
            configured_charts=[],
            sort_expression=[{
                'field': 'just_for_sorting',
                'order': 'DESC'
            }])
        self.report_config.save()
        self.addCleanup(self.report_config.delete)

    def _add_some_rows(self, count):
        rows = [
            ReportDataTestRow(uuid.uuid4().hex, i, i) for i in range(count)
        ]
        self._add_rows(rows)
        return rows

    def _add_rows(self, rows):
        pillow = get_kafka_ucr_pillow()
        pillow.bootstrap(configs=[self.data_source])

        def _get_case(row):
            return {
                '_id': uuid.uuid4().hex,
                'domain': self.domain,
                'doc_type': 'CommCareCase',
                'type': 'city',
                'name': row.name,
                'number': row.number,
                'just_for_sorting': row.sort_key,
            }

        for row in rows:
            pillow.process_change(doc_to_change(_get_case(row)))

    def test_basic_query(self):
        # add a few rows to the data source
        rows = self._add_some_rows(3)

        # check the returned data from the report looks right
        report_data_source = ConfigurableReportDataSource.from_spec(
            self.report_config)
        report_data = report_data_source.get_data()
        self.assertEqual(len(rows), len(report_data))
        rows_by_name = {r.name: r for r in rows}
        for row in report_data:
            self.assertTrue(row['name'] in rows_by_name)
            self.assertEqual(rows_by_name[row['name']].number, row['number'])
            self.assertEqual(10, row['ten'])
            self.assertEqual(10 * row['number'], row['by_tens'])

    def test_limit(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ConfigurableReportDataSource.from_spec(
            self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        limited_data = report_data_source.get_data(limit=3)
        self.assertEqual(3, len(limited_data))
        self.assertEqual(original_data[:3], limited_data)

    def test_skip(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ConfigurableReportDataSource.from_spec(
            self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        skipped = report_data_source.get_data(start=3)
        self.assertEqual(count - 3, len(skipped))
        self.assertEqual(original_data[3:], skipped)

    def test_total_row(self):
        rows = self._add_some_rows(3)
        report_data_source = ConfigurableReportDataSource.from_spec(
            self.report_config)

        total_number = sum(row.number for row in rows)
        self.assertEqual(report_data_source.get_total_row(),
                         ['Total', total_number, '', '', ''])

    def test_transform(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ConfigurableReportDataSource.from_spec(
            self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        rows_by_number = {int(row['number']): row for row in original_data}
        # Make sure the translations happened
        self.assertEqual(rows_by_number[0]['string-number'], "zero")
        self.assertEqual(rows_by_number[1]['string-number'], "one")
        self.assertEqual(rows_by_number[2]['string-number'], "two")
        # These last two are untranslated
        self.assertEqual(rows_by_number[3]['string-number'], "3")
        self.assertEqual(rows_by_number[4]['string-number'], "4")
Пример #27
0
class ReportDataTest(TestCase):
    def setUp(self):
        super(ReportDataTest, self).setUp()
        # Create report
        self.domain = "test-ucr-report-data"
        self.data_source = DataSourceConfiguration(
            domain=self.domain,
            referenced_doc_type="CommCareCase",
            table_id=uuid.uuid4().hex,
            configured_filter={},
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {"type": "property_name", "property_name": "name"},
                    "column_id": "name",
                    "display_name": "name",
                    "datatype": "string",
                },
                {
                    "type": "expression",
                    "expression": {"type": "property_name", "property_name": "number"},
                    "column_id": "number",
                    "display_name": "number",
                    "datatype": "integer",
                },
            ],
        )
        self.data_source.validate()
        self.data_source.save()
        self.adapter = get_indicator_adapter(self.data_source)
        self.adapter.rebuild_table()
        self.addCleanup(self.data_source.delete)

        # initialize a report on the data
        self.report_config = ReportConfiguration(
            domain=self.domain,
            config_id=self.data_source._id,
            aggregation_columns=["doc_id"],
            columns=[
                {"type": "field", "field": "name", "column_id": "name", "display": "Name", "aggregation": "simple"},
                {
                    "type": "field",
                    "field": "number",
                    "column_id": "number",
                    "display": "Number",
                    "aggregation": "simple",
                },
                {
                    "type": "expression",
                    "column_id": "ten",
                    "display": "The Number Ten",
                    "expression": {"type": "constant", "constant": 10},
                },
                {
                    "type": "expression",
                    "column_id": "by_tens",
                    "display": "Counting by tens",
                    "expression": {
                        "type": "evaluator",
                        "statement": "a * b",
                        "context_variables": {
                            "a": {"type": "property_name", "property_name": "number"},
                            "b": {"type": "property_name", "property_name": "ten"},
                        },
                    },
                },
            ],
            filters=[],
            configured_charts=[],
        )
        self.report_config.save()
        self.addCleanup(self.report_config.delete)

    def _add_some_rows(self, count):
        rows = [ReportDataTestRow(uuid.uuid4().hex, i) for i in range(count)]
        self._add_rows(rows)
        self.adapter.refresh_table()
        return rows

    def _add_rows(self, rows):
        pillow = get_kafka_ucr_pillow()
        pillow.bootstrap(configs=[self.data_source])

        def _get_case(row):
            return {
                "_id": uuid.uuid4().hex,
                "domain": self.domain,
                "doc_type": "CommCareCase",
                "type": "city",
                "name": row.name,
                "number": row.number,
            }

        for row in rows:
            pillow.process_change(doc_to_change(_get_case(row)))

    @run_with_all_ucr_backends
    def test_basic_query(self):
        # add a few rows to the data source
        rows = self._add_some_rows(3)

        # check the returned data from the report looks right
        report_data_source = ReportFactory.from_spec(self.report_config)
        report_data = report_data_source.get_data()
        self.assertEqual(len(rows), len(report_data))
        rows_by_name = {r.name: r for r in rows}
        for row in report_data:
            self.assertTrue(row["name"] in rows_by_name)
            self.assertEqual(rows_by_name[row["name"]].number, row["number"])
            self.assertEqual(10, row["ten"])
            self.assertEqual(10 * row["number"], row["by_tens"])

    @run_with_all_ucr_backends
    def test_limit(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ReportFactory.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        limited_data = report_data_source.get_data(limit=3)
        self.assertEqual(3, len(limited_data))
        self.assertEqual(original_data[:3], limited_data)

    @run_with_all_ucr_backends
    def test_skip(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ReportFactory.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        skipped = report_data_source.get_data(start=3)
        self.assertEqual(count - 3, len(skipped))
        self.assertEqual(original_data[3:], skipped)
Пример #28
0
    def _build_report(self, vals, field='my_field', build_data_source=True):
        """
        Build a new report, and populate it with cases.

        Return a ConfigurableReportDataSource and a FieldColumn
        :param vals: List of values to populate the given report field with.
        :param field: The name of a field in the data source/report
        :return: Tuple containing a ConfigurableReportDataSource and FieldColumn.
        The column is a column mapped to the given field.
        """

        # Create Cases
        for v in vals:
            update_props = {field: v} if v is not None else {}
            self._new_case(update_props).save()

        # Create report
        data_source_config = DataSourceConfiguration(
            domain=self.domain,
            display_name='foo',
            referenced_doc_type='CommCareCase',
            table_id=_clean_table_name(self.domain, str(uuid.uuid4().hex)),
            configured_filter={
                "type": "boolean_expression",
                "operator": "eq",
                "expression": {
                    "type": "property_name",
                    "property_name": "type"
                },
                "property_value": self.case_type,
            },
            configured_indicators=[{
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": field
                },
                "column_id": field,
                "display_name": field,
                "datatype": "string"
            }],
        )
        data_source_config.validate()
        data_source_config.save()
        self.addCleanup(data_source_config.delete)
        if build_data_source:
            tasks.rebuild_indicators(data_source_config._id)
            adapter = get_indicator_adapter(data_source_config)
            adapter.refresh_table()

        report_config = ReportConfiguration(domain=self.domain,
                                            config_id=data_source_config._id,
                                            title='foo',
                                            aggregation_columns=['doc_id'],
                                            columns=[{
                                                "type": "expanded",
                                                "field": field,
                                                "display": field,
                                                "format": "default",
                                            }],
                                            filters=[],
                                            configured_charts=[])
        report_config.save()
        self.addCleanup(report_config.delete)
        data_source = ReportFactory.from_spec(report_config)
        adapter = get_indicator_adapter(data_source_config)
        if build_data_source:
            adapter.refresh_table()

        return data_source, data_source.top_level_columns[0]
    def test_report_builder_datasource_deactivation(self):

        def _get_data_source(id_):
            return get_datasource_config(id_, self.project.name)[0]

        # Upgrade the domain
        # (for the upgrade to work, there has to be an existing subscription,
        # which is why we subscribe to advanced first)
        self._subscribe_to_advanced()
        pro_with_rb_sub = self._subscribe_to_pro_with_rb()

        # Create reports and data sources
        builder_report_data_source = DataSourceConfiguration(
            domain=self.project.name,
            is_deactivated=False,
            referenced_doc_type="XFormInstance",
            table_id="foo",

        )
        other_data_source = DataSourceConfiguration(
            domain=self.project.name,
            is_deactivated=False,
            referenced_doc_type="XFormInstance",
            table_id="bar",
        )
        builder_report_data_source.save()
        other_data_source.save()
        report_builder_report = ReportConfiguration(
            domain=self.project.name,
            config_id=builder_report_data_source._id,
            report_meta=ReportMeta(created_by_builder=True),
        )
        report_builder_report.save()

        # downgrade the domain
        pro_with_rb_sub.cancel_subscription(web_user=self.admin_user.username)

        # Check that the builder data source is deactivated
        builder_report_data_source = _get_data_source(builder_report_data_source._id)
        self.assertTrue(builder_report_data_source.is_deactivated)
        # Check that the other data source has not been deactivated
        other_data_source = _get_data_source(other_data_source._id)
        self.assertFalse(other_data_source.is_deactivated)

        # upgrade the domain
        # (for the upgrade to work, there has to be an existing subscription,
        # which is why we subscribe to advanced first)
        self._subscribe_to_advanced()
        pro_with_rb_sub = self._subscribe_to_pro_with_rb()

        # check that the data source is activated
        builder_report_data_source = _get_data_source(builder_report_data_source._id)
        self.assertFalse(builder_report_data_source.is_deactivated)

        # delete the data sources
        builder_report_data_source.delete()
        other_data_source.delete()
        # Delete the report
        report_builder_report.delete()

        # reset the subscription
        pro_with_rb_sub.cancel_subscription(web_user=self.admin_user.username)
Пример #30
0
    def _build_report_and_view(cls):

        # Create Cases
        cls._new_case({'fruit': 'apple', 'num1': 4, 'num2': 6}).save()

        # Create report
        data_source_config = DataSourceConfiguration(
            domain=cls.domain,
            display_name='foo',
            referenced_doc_type='CommCareCase',
            table_id="woop_woop",
            configured_filter={
                "type": "boolean_expression",
                "operator": "eq",
                "expression": {
                    "type": "property_name",
                    "property_name": "type"
                },
                "property_value": cls.case_type,
            },
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'fruit'
                    },
                    "column_id": 'indicator_col_id_fruit',
                    "display_name": 'indicator_display_name_fruit',
                    "datatype": "string"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'num1'
                    },
                    "column_id": 'indicator_col_id_num1',
                    "datatype": "integer"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'num2'
                    },
                    "column_id": 'indicator_col_id_num2',
                    "datatype": "integer"
                },
            ],
        )
        data_source_config.validate()
        data_source_config.save()
        tasks.rebuild_indicators(data_source_config._id)

        report_config = ReportConfiguration(
            domain=cls.domain,
            config_id=data_source_config._id,
            title='foo',
            aggregation_columns=['doc_id'],
            columns=[
                {
                    "type": "field",
                    "display": "report_column_display_fruit",
                    "field": 'indicator_col_id_fruit',
                    'column_id': 'report_column_col_id_fruit',
                    'aggregation': 'simple'
                },
                {
                    "type": "percent",
                    "display": "report_column_display_percent",
                    'column_id': 'report_column_col_id_percent',
                    'format': 'percent',
                    "denominator": {
                        "type": "field",
                        "aggregation": "sum",
                        "field": "indicator_col_id_num1",
                        "column_id": "report_column_col_id_percent_num1"
                    },
                    "numerator": {
                        "type": "field",
                        "aggregation": "sum",
                        "field": "indicator_col_id_num2",
                        "column_id": "report_column_col_id_percent_num2"
                    }
                },
            ],
        )
        report_config.save()

        view = ConfigurableReport(request=HttpRequest())
        view._domain = cls.domain
        view._lang = "en"
        view._report_config_id = report_config._id

        return report_config, view
Пример #31
0
class ReportDataTest(TestCase):
    dependent_apps = ['pillowtop']

    def setUp(self):
        # Create report
        self.domain = 'test-ucr-report-data'
        self.data_source = DataSourceConfiguration(
            domain=self.domain,
            referenced_doc_type='CommCareCase',
            table_id=uuid.uuid4().hex,
            configured_filter={},
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'name'
                    },
                    "column_id": 'name',
                    "display_name": 'name',
                    "datatype": "string"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'number'
                    },
                    "column_id": 'number',
                    "display_name": 'number',
                    "datatype": "integer"
                }
            ],
        )
        self.data_source.validate()
        self.data_source.save()
        IndicatorSqlAdapter(self.data_source).rebuild_table()
        self.addCleanup(self.data_source.delete)

        # initialize a report on the data
        self.report_config = ReportConfiguration(
            domain=self.domain,
            config_id=self.data_source._id,
            aggregation_columns=['doc_id'],
            columns=[
                {
                    "type": "field",
                    "field": "name",
                    "column_id": "name",
                    "display": "Name",
                    "aggregation": "simple",
                },
                {
                    "type": "field",
                    "field": "number",
                    "column_id": "number",
                    "display": "Number",
                    "aggregation": "simple",
                }
            ],
            filters=[],
            configured_charts=[]
        )
        self.report_config.save()
        self.addCleanup(self.report_config.delete)

    def _add_some_rows(self, count):
        rows = [ReportDataTestRow(uuid.uuid4().hex, i) for i in range(count)]
        self._add_rows(rows)
        return rows

    def _add_rows(self, rows):
        pillow = get_kafka_ucr_pillow()
        pillow.bootstrap(configs=[self.data_source])

        def _get_case(row):
            return {
                '_id': uuid.uuid4().hex,
                'domain': self.domain,
                'doc_type': 'CommCareCase',
                'type': 'city',
                'name': row.name,
                'number': row.number,
            }
        for row in rows:
            pillow.process_change(doc_to_change(_get_case(row)))

    def test_basic_query(self):
        # add a few rows to the data source
        rows = self._add_some_rows(3)

        # check the returned data from the report looks right
        report_data_source = ReportFactory.from_spec(self.report_config)
        report_data = report_data_source.get_data()
        self.assertEqual(len(rows), len(report_data))
        rows_by_name = {r.name: r for r in rows}
        for row in report_data:
            self.assertTrue(row['name'] in rows_by_name)
            self.assertEqual(rows_by_name[row['name']].number, row['number'])

    def test_limit(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ReportFactory.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        limited_data = report_data_source.get_data(limit=3)
        self.assertEqual(3, len(limited_data))
        self.assertEqual(original_data[:3], limited_data)

    def test_skip(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ReportFactory.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        skipped = report_data_source.get_data(start=3)
        self.assertEqual(count - 3, len(skipped))
        self.assertEqual(original_data[3:], skipped)
Пример #32
0
    def _build_report_and_view(self):
        # Create report
        data_source_config = DataSourceConfiguration(
            domain=self.domain,
            display_name='foo',
            referenced_doc_type='CommCareCase',
            table_id="woop_woop",
            configured_filter={
                "type": "boolean_expression",
                "operator": "eq",
                "expression": {
                    "type": "property_name",
                    "property_name": "type"
                },
                "property_value": self.case_type,
            },
            configured_indicators=[
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'fruit'
                    },
                    "column_id": 'indicator_col_id_fruit',
                    "display_name": 'indicator_display_name_fruit',
                    "datatype": "string"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'num1'
                    },
                    "column_id": 'indicator_col_id_num1',
                    "datatype": "integer"
                },
                {
                    "type": "expression",
                    "expression": {
                        "type": "property_name",
                        "property_name": 'num2'
                    },
                    "column_id": 'indicator_col_id_num2',
                    "datatype": "integer"
                },
            ],
        )
        data_source_config.validate()
        data_source_config.save()
        self.addCleanup(data_source_config.delete)
        tasks.rebuild_indicators(data_source_config._id)
        adapter = get_indicator_adapter(data_source_config)
        adapter.refresh_table()

        report_config = ReportConfiguration(
            domain=self.domain,
            config_id=data_source_config._id,
            title='foo',
            aggregation_columns=['doc_id'],
            columns=[
                {
                    "type": "field",
                    "display": "report_column_display_fruit",
                    "field": 'indicator_col_id_fruit',
                    'column_id': 'report_column_col_id_fruit',
                    'aggregation': 'simple'
                },
                {
                    "type": "percent",
                    "display": "report_column_display_percent",
                    'column_id': 'report_column_col_id_percent',
                    'format': 'percent',
                    "denominator": {
                        "type": "field",
                        "aggregation": "sum",
                        "field": "indicator_col_id_num1",
                        "column_id": "report_column_col_id_percent_num1"
                    },
                    "numerator": {
                        "type": "field",
                        "aggregation": "sum",
                        "field": "indicator_col_id_num2",
                        "column_id": "report_column_col_id_percent_num2"
                    }
                },
            ],
        )
        report_config.save()
        self.addCleanup(report_config.delete)

        view = ConfigurableReport(request=HttpRequest())
        view._domain = self.domain
        view._lang = "en"
        view._report_config_id = report_config._id

        return report_config, view
Пример #33
0
class ReportDataTest(TestCase):
    def setUp(self):
        super(ReportDataTest, self).setUp()
        # Create report
        self.domain = 'test-ucr-report-data'
        self.data_source = DataSourceConfiguration(
            domain=self.domain,
            referenced_doc_type='CommCareCase',
            table_id=uuid.uuid4().hex,
            configured_filter={},
            configured_indicators=[{
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": 'name'
                },
                "column_id": 'name',
                "display_name": 'name',
                "datatype": "string"
            }, {
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": 'number'
                },
                "column_id": 'number',
                "display_name": 'number',
                "datatype": "integer"
            }],
        )
        self.data_source.validate()
        self.data_source.save()
        self.adapter = get_indicator_adapter(self.data_source)
        self.adapter.rebuild_table()
        self.addCleanup(self.data_source.delete)

        # initialize a report on the data
        self.report_config = ReportConfiguration(
            domain=self.domain,
            config_id=self.data_source._id,
            aggregation_columns=['doc_id'],
            columns=[{
                "type": "field",
                "field": "name",
                "column_id": "name",
                "display": "Name",
                "aggregation": "simple",
            }, {
                "type": "field",
                "field": "number",
                "column_id": "number",
                "display": "Number",
                "aggregation": "simple",
            }, {
                "type": "expression",
                "column_id": "ten",
                "display": "The Number Ten",
                "expression": {
                    'type': 'constant',
                    'constant': 10,
                }
            }, {
                "type": "expression",
                "column_id": "by_tens",
                "display": "Counting by tens",
                "expression": {
                    "type": "evaluator",
                    "statement": "a * b",
                    "context_variables": {
                        "a": {
                            "type": "property_name",
                            "property_name": "number",
                        },
                        "b": {
                            "type": "property_name",
                            "property_name": "ten",
                        }
                    }
                }
            }],
            filters=[],
            configured_charts=[])
        self.report_config.save()
        self.addCleanup(self.report_config.delete)

    def _add_some_rows(self, count):
        rows = [ReportDataTestRow(uuid.uuid4().hex, i) for i in range(count)]
        self._add_rows(rows)
        self.adapter.refresh_table()
        return rows

    def _add_rows(self, rows):
        pillow = get_kafka_ucr_pillow()
        pillow.bootstrap(configs=[self.data_source])

        def _get_case(row):
            return {
                '_id': uuid.uuid4().hex,
                'domain': self.domain,
                'doc_type': 'CommCareCase',
                'type': 'city',
                'name': row.name,
                'number': row.number,
            }

        for row in rows:
            pillow.process_change(doc_to_change(_get_case(row)))

    @run_with_all_ucr_backends
    def test_basic_query(self):
        # add a few rows to the data source
        rows = self._add_some_rows(3)

        # check the returned data from the report looks right
        report_data_source = ReportFactory.from_spec(self.report_config)
        report_data = report_data_source.get_data()
        self.assertEqual(len(rows), len(report_data))
        rows_by_name = {r.name: r for r in rows}
        for row in report_data:
            self.assertTrue(row['name'] in rows_by_name)
            self.assertEqual(rows_by_name[row['name']].number, row['number'])
            self.assertEqual(10, row['ten'])
            self.assertEqual(10 * row['number'], row['by_tens'])

    @run_with_all_ucr_backends
    def test_limit(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ReportFactory.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        limited_data = report_data_source.get_data(limit=3)
        self.assertEqual(3, len(limited_data))
        self.assertEqual(original_data[:3], limited_data)

    @run_with_all_ucr_backends
    def test_skip(self):
        count = 5
        self._add_some_rows(count)
        report_data_source = ReportFactory.from_spec(self.report_config)
        original_data = report_data_source.get_data()
        self.assertEqual(count, len(original_data))
        skipped = report_data_source.get_data(start=3)
        self.assertEqual(count - 3, len(skipped))
        self.assertEqual(original_data[3:], skipped)
    def test_report_builder_datasource_deactivation(self):
        def _get_data_source(id_):
            return get_datasource_config(id_, self.project.name)[0]

        # Upgrade the domain
        # (for the upgrade to work, there has to be an existing subscription,
        # which is why we subscribe to advanced first)
        self._subscribe_to_advanced()
        pro_with_rb_sub = self._subscribe_to_pro_with_rb()

        # Create reports and data sources
        builder_report_data_source = DataSourceConfiguration(
            domain=self.project.name,
            is_deactivated=False,
            referenced_doc_type="XFormInstance",
            table_id="foo",
        )
        other_data_source = DataSourceConfiguration(
            domain=self.project.name,
            is_deactivated=False,
            referenced_doc_type="XFormInstance",
            table_id="bar",
        )
        builder_report_data_source.save()
        other_data_source.save()
        report_builder_report = ReportConfiguration(
            domain=self.project.name,
            config_id=builder_report_data_source._id,
            report_meta=ReportMeta(created_by_builder=True),
        )
        report_builder_report.save()

        # downgrade the domain
        community_sub = pro_with_rb_sub.change_plan(
            DefaultProductPlan.get_default_plan_version())

        # Check that the builder data source is deactivated
        builder_report_data_source = _get_data_source(
            builder_report_data_source._id)
        self.assertTrue(builder_report_data_source.is_deactivated)
        # Check that the other data source has not been deactivated
        other_data_source = _get_data_source(other_data_source._id)
        self.assertFalse(other_data_source.is_deactivated)

        # upgrade the domain
        # (for the upgrade to work, there has to be an existing subscription,
        # which is why we subscribe to advanced first)
        community_sub.change_plan(
            DefaultProductPlan.get_default_plan_version(
                edition=SoftwarePlanEdition.ADVANCED))
        pro_with_rb_sub = self._subscribe_to_pro_with_rb()

        # check that the data source is activated
        builder_report_data_source = _get_data_source(
            builder_report_data_source._id)
        self.assertFalse(builder_report_data_source.is_deactivated)

        # delete the data sources
        builder_report_data_source.delete()
        other_data_source.delete()
        # Delete the report
        report_builder_report.delete()

        # reset the subscription
        pro_with_rb_sub.change_plan(
            DefaultProductPlan.get_default_plan_version())
Пример #35
0
    def _build_report(self, vals, field='my_field', build_data_source=True):
        """
        Build a new report, and populate it with cases.

        Return a ConfigurableReportDataSource and a FieldColumn
        :param vals: List of values to populate the given report field with.
        :param field: The name of a field in the data source/report
        :return: Tuple containing a ConfigurableReportDataSource and FieldColumn.
        The column is a column mapped to the given field.
        """

        # Create Cases
        for v in vals:
            update_props = {field: v} if v is not None else {}
            self._new_case(update_props).save()

        # Create report
        data_source_config = DataSourceConfiguration(
            domain=self.domain,
            display_name='foo',
            referenced_doc_type='CommCareCase',
            table_id=_clean_table_name(self.domain, str(uuid.uuid4().hex)),
            configured_filter={
                "type": "boolean_expression",
                "operator": "eq",
                "expression": {
                    "type": "property_name",
                    "property_name": "type"
                },
                "property_value": self.case_type,
            },
            configured_indicators=[{
                "type": "expression",
                "expression": {
                    "type": "property_name",
                    "property_name": field
                },
                "column_id": field,
                "display_name": field,
                "datatype": "string"
            }],
        )
        data_source_config.validate()
        data_source_config.save()
        self.addCleanup(data_source_config.delete)
        if build_data_source:
            tasks.rebuild_indicators(data_source_config._id)
            adapter = get_indicator_adapter(data_source_config)
            adapter.refresh_table()

        report_config = ReportConfiguration(
            domain=self.domain,
            config_id=data_source_config._id,
            title='foo',
            aggregation_columns=['doc_id'],
            columns=[{
                "type": "expanded",
                "field": field,
                "display": field,
                "format": "default",
            }],
            filters=[],
            configured_charts=[]
        )
        report_config.save()
        self.addCleanup(report_config.delete)
        data_source = ReportFactory.from_spec(report_config)
        adapter = get_indicator_adapter(data_source_config)
        if build_data_source:
            adapter.refresh_table()

        return data_source, data_source.top_level_columns[0]
Пример #36
0
    def setUpClass(cls):
        super(TestSimpleReportConfigurationResource, cls).setUpClass()

        cls.report_columns = [
            {
                "column_id": 'foo',
                "display": "foo display",
                "type": "field",
                "field": "my_field",
                "aggregation": "simple",
            },
            {
                "column_id": 'bar',
                "display": "bar display",
                "type": "field",
                "field": "my_field",
                "aggregation": "simple",
            },
            {
                "column_id": 'expand',
                "display": "expand display",
                "type": "expanded",
                "field": "my_field",
                "max_expansion": 10,
            }
        ]
        cls.report_filters = [
            {
                'datatype': 'integer',
                'field': 'my_field',
                'type': 'dynamic_choice_list',
                'slug': 'my_field_filter',
            },
            {
                'datatype': 'string',
                'field': 'my_other_field',
                'type': 'dynamic_choice_list',
                'slug': 'my_other_field_filter',
            }
        ]
        cls.report_title = "test report"

        cls.data_source = DataSourceConfiguration(
            domain=cls.domain.name,
            referenced_doc_type="XFormInstance",
            table_id=uuid.uuid4().hex,
        )
        cls.data_source.save()

        cls.report_configuration = ReportConfiguration(
            title=cls.report_title,
            domain=cls.domain.name,
            config_id=cls.data_source._id,
            columns=cls.report_columns,
            filters=cls.report_filters
        )
        cls.report_configuration.save()

        another_report_configuration = ReportConfiguration(
            domain=cls.domain.name, config_id=cls.data_source._id, columns=[], filters=[]
        )
        another_report_configuration.save()