Example #1
0
    def setUp(self):
        management.call_command('avocado', 'sync', 'export', quiet=True)
        first_name_field = DataField.objects.get_by_natural_key('export', 'employee', 'first_name')
        first_name_field.description = 'First Name'
        last_name_field = DataField.objects.get_by_natural_key('export', 'employee', 'last_name')
        last_name_field.description = 'Last Name'
        title_field = DataField.objects.get_by_natural_key('export', 'title', 'name')
        title_field.description = 'Employee Title'
        salary_field = DataField.objects.get_by_natural_key('export', 'title', 'salary')
        salary_field.description = 'Salary'
        is_manager_field = DataField.objects.get_by_natural_key('export', 'employee', 'is_manager')
        is_manager_field.description = 'Is a Manager?'

        [x.save() for x in [first_name_field, last_name_field, title_field,
            salary_field, is_manager_field]]

        employee_concept = DataConcept()
        employee_concept.name = 'Employee'
        employee_concept.description = 'A Single Employee'
        employee_concept.save()

        DataConceptField(concept=employee_concept, field=first_name_field, order=1).save()
        DataConceptField(concept=employee_concept, field=last_name_field, order=2).save()
        DataConceptField(concept=employee_concept, field=is_manager_field, order=3).save()
        DataConceptField(concept=employee_concept, field=title_field, order=4).save()
        DataConceptField(concept=employee_concept, field=salary_field, order=5).save()

        self.concepts = [employee_concept]

        self.query = models.Employee.objects.values_list('first_name', 'last_name',
                'is_manager', 'title__name', 'title__salary')
Example #2
0
    def setUp(self):
        management.call_command("avocado", "init", "tests", quiet=True)
        first_name_field = DataField.objects.get_by_natural_key("tests", "employee", "first_name")
        first_name_field.description = "First Name"
        last_name_field = DataField.objects.get_by_natural_key("tests", "employee", "last_name")
        last_name_field.description = "Last Name"
        title_field = DataField.objects.get_by_natural_key("tests", "title", "name")
        title_field.description = "Employee Title"
        salary_field = DataField.objects.get_by_natural_key("tests", "title", "salary")
        salary_field.description = "Salary"
        is_manager_field = DataField.objects.get_by_natural_key("tests", "employee", "is_manager")
        is_manager_field.description = "Is a Manager?"

        [x.save() for x in [first_name_field, last_name_field, title_field, salary_field, is_manager_field]]

        employee_concept = DataConcept()
        employee_concept.name = "Employee"
        employee_concept.description = "A Single Employee"
        employee_concept.save()

        DataConceptField(concept=employee_concept, field=first_name_field, order=1).save()
        DataConceptField(concept=employee_concept, field=last_name_field, order=2).save()
        DataConceptField(concept=employee_concept, field=is_manager_field, order=3).save()
        DataConceptField(concept=employee_concept, field=title_field, order=4).save()
        DataConceptField(concept=employee_concept, field=salary_field, order=5).save()

        self.concepts = [employee_concept]

        self.query = models.Employee.objects.values_list(
            "first_name", "last_name", "is_manager", "title__name", "title__salary"
        )
Example #3
0
    def test_published(self):
        concept = DataConcept(published=True)
        concept.save()
        DataConceptField(concept=concept, field=self.is_manager).save()
        DataConceptField(concept=concept, field=self.salary).save()

        # Published, not specific to any user
        self.assertEqual([x.pk for x in DataConcept.objects.published()], [])

        self.is_manager.published = True
        self.is_manager.save()
        self.salary.published = True
        self.salary.save()

        # Now published, it will appear
        self.assertEqual([x.pk for x in DataConcept.objects.published()], [1])

        user1 = User.objects.create_user('user1', 'user1')

        # Nothing since user1 cannot view either datafield
        self.assertEqual([x.pk for x in DataConcept.objects.published(user1)], [])

        assign('avocado.view_datafield', user1, self.is_manager)
        # Still nothing since user1 has no permission for salary
        self.assertEqual([x.pk for x in DataConcept.objects.published(user1)], [])

        assign('avocado.view_datafield', user1, self.salary)
        # Now user1 can see the concept
        self.assertEqual([x.pk for x in DataConcept.objects.published(user1)], [1])

        user2 = User.objects.create_user('user2', 'user2')

        # `user2` is not assigned
        self.assertEqual([x.pk for x in DataConcept.objects.published(user2)], [])
Example #4
0
    def test_implicit_apply_distinct(self):
        f1 = DataField.objects.get_by_natural_key('tests',
                                                  'office',
                                                  'location')
        f2 = DataField.objects.get_by_natural_key('tests',
                                                  'title',
                                                  'name')
        c = DataConcept()
        c.save()

        DataConceptField(concept=c, field=f1).save()
        DataConceptField(concept=c, field=f2).save()

        # Due to the use of distinct, the concept fields appear in the SELECT
        # statement at this point. This is not a bug, but a requirement of SQL.
        # These columns are stripped downstream by the exporter.
        node = parsers.dataview.parse([{
            'concept': c.pk,
            'sort': 'desc',
            'visible': False,
        }], tree=Employee)

        self.assertEqual(
            unicode(node.apply(Employee.objects.distinct()).query)
            .replace(' ', ''),
            'SELECT DISTINCT "tests_employee"."id", '
            '"tests_office"."location", "tests_title"."name" FROM '
            '"tests_employee" INNER JOIN "tests_office" ON '
            '("tests_employee"."office_id" = "tests_office"."id") LEFT OUTER '
            'JOIN "tests_title" ON ("tests_employee"."title_id" = '
            '"tests_title"."id") ORDER BY "tests_office"."location" DESC, '
            '"tests_title"."name" DESC'
            .replace(' ', ''))
Example #5
0
 def create_dataconcept_single(self, request, queryset):
     fields = list(queryset)
     max_length = DataConcept._meta.get_field_by_name('name')[0].max_length
     name = ', '.join([f.name for f in fields])[:max_length - 5] + '...'
     concept = DataConcept(name='"{0}"'.format(name))
     concept.save()
     for i, datafield in enumerate(queryset):
         DataConceptField(concept=concept, field=datafield, order=i).save()
Example #6
0
    def setUp(self):
        management.call_command('avocado', 'init', 'query', quiet=True)
        f1 = DataField.objects.get(pk=1)
        f2 = DataField.objects.get(pk=2)

        c1 = DataConcept()
        c1.save()

        DataConceptField(concept=c1, field=f1).save()
        DataConceptField(concept=c1, field=f2).save()
Example #7
0
    def setUp(self):
        super(ConceptResourceTestCase, self).setUp()

        self.name_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'name')
        self.salary_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'salary')
        self.boss_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'boss')

        cat = DataCategory(name='Test', published=True, order=1.0)
        cat.save()

        c1 = DataConcept(name='Title', published=True, category=cat)
        c1.save()
        DataConceptField(concept=c1, field=self.name_field, order=1).save()
        DataConceptField(concept=c1, field=self.salary_field, order=2).save()
        DataConceptField(concept=c1, field=self.boss_field, order=3).save()

        # Not published
        c2 = DataConcept(name='Salary', category=cat)
        c2.save()
        DataConceptField(concept=c2, field=self.salary_field, order=1).save()
        DataConceptField(concept=c2, field=self.boss_field, order=2).save()

        c3 = DataConcept(name='Name', published=True, category=cat)
        c3.save()
        DataConceptField(concept=c3, field=self.name_field, order=1).save()

        self.c1 = c1
        self.c2 = c2
        self.c3 = c3
Example #8
0
    def test_dataview_order_by(self):
        f = DataField(app_name='lexicon', model_name='month', field_name='id')
        f.save()

        c = DataConcept()
        c.save()

        cf = DataConceptField(field=f, concept=c)
        cf.save()

        v = DataView({'ordering': [c.pk]})

        qs = Month.objects.filter(label__startswith='J').values('id')
        self.assertEqual(str(v.apply(qs).query), 'SELECT "lexicon_month"."id" FROM "lexicon_month" WHERE "lexicon_month"."label" LIKE J% ESCAPE \'\\\'  ORDER BY "lexicon_month"."order" ASC')
Example #9
0
    def create_dataconcept_single(self, request, queryset):
        fields = list(queryset)

        # If only a single field is selected with this action, directly map
        if len(fields) == 1:
            DataConcept.objects.create_from_field(fields[0])
            return

        max_length = DataConcept._meta.get_field_by_name('name')[0].max_length
        name = ', '.join([f.name for f in fields])[:max_length - 5] + '...'
        concept = DataConcept(name=u'"{0}"'.format(name))
        concept.save()
        for i, datafield in enumerate(queryset):
            DataConceptField(concept=concept, field=datafield, order=i).save()
Example #10
0
    def create_dataconcept_single(self, request, queryset):
        fields = list(queryset)

        # If only a single field is selected with this action, directly map
        if len(fields) == 1:
            DataConcept.objects.create_from_field(fields[0])
            return

        max_length = DataConcept._meta.get_field_by_name("name")[0].max_length
        name = ", ".join([f.name for f in fields])[: max_length - 5] + "..."
        concept = DataConcept(name=u'"{0}"'.format(name))
        concept.save()
        for i, datafield in enumerate(queryset):
            DataConceptField(concept=concept, field=datafield, order=i).save()
Example #11
0
    def test_field_for_concept(self):
        f = DataField.objects.get(model_name='title', field_name='name')
        c1 = DataConcept()
        c2 = DataConcept()
        c1.save()
        c2.save()
        cf = DataConceptField(concept=c1, field=f)
        cf.save()

        attrs = {
            'concept': c1.pk,
            'field': f.pk,
            'operator': 'exact',
            'value': 'CEO',
            'cleaned_value': {'value': 'CEO', 'label': 'CEO'},
            'language': 'Name is CEO'
        }

        self.assertEqual(
            parsers.datacontext.validate(deepcopy(attrs), tree=Employee),
            attrs)

        # Invalid concept
        attrs = parsers.datacontext.validate({
            'concept': c2.pk,
            'field': f.pk,
            'operator': 'exact',
            'value': 'CEO',
        }, tree=Employee)

        self.assertFalse(attrs['enabled'])
Example #12
0
    def setUp(self):
        management.call_command('avocado', 'init', 'tests', publish=False,
                                concepts=False, quiet=True)
        f1 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'first_name')
        f2 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'last_name')

        self.c = DataConcept()
        self.c.save()

        DataConceptField(concept=self.c, field=f1).save()
        DataConceptField(concept=self.c, field=f2).save()
Example #13
0
    def setUp(self):
        management.call_command('avocado',
                                'init',
                                'tests',
                                publish=False,
                                concepts=False,
                                quiet=True)
        f1 = DataField.objects.get(pk=1)
        f2 = DataField.objects.get(pk=2)

        c1 = DataConcept()
        c1.save()

        DataConceptField(concept=c1, field=f1).save()
        DataConceptField(concept=c1, field=f2).save()
Example #14
0
    def setUp(self):
        management.call_command('avocado', 'init', 'tests', quiet=True)

        f1 = DataField.objects.get(pk=1)
        f2 = DataField.objects.get(pk=2)

        c1 = DataConcept()
        c1.save()

        DataConceptField(concept=c1, field=f1).save()
        DataConceptField(concept=c1, field=f2).save()

        self.request = HttpRequest()
        self.request.session = SessionStore()
        self.request.session.save()
Example #15
0
    def setUp(self):
        management.call_command('avocado', 'init', 'tests', quiet=True)

        f1 = DataField.objects.get(pk=1)
        f2 = DataField.objects.get(pk=2)

        c1 = DataConcept()
        c1.save()

        DataConceptField(concept=c1, field=f1).save()
        DataConceptField(concept=c1, field=f2).save()

        self.request = HttpRequest()
        self.request.session = SessionStore()
        self.request.session.save()
Example #16
0
    def setUp(self):
        super(ConceptFieldResourceTestCase, self).setUp()

        self.name_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'name')
        self.salary_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'salary')
        self.boss_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'boss')

        c1 = DataConcept(name='Title', published=True)
        c1.save()
        DataConceptField(concept=c1, field=self.name_field, order=1).save()
        DataConceptField(concept=c1, field=self.salary_field, order=2).save()
        DataConceptField(concept=c1, field=self.boss_field, order=3).save()
Example #17
0
    def test_unique_keys(self):
        title_name = DataField.objects.get_by_natural_key('tests', 'title', 'name')
        project_name = DataField.objects.get_by_natural_key('tests', 'project', 'name')

        concept = DataConcept()
        concept.save()

        DataConceptField(concept=concept, field=title_name, order=1).save()
        DataConceptField(concept=concept, field=project_name, order=2).save()

        f = Formatter(concept)

        self.assertEqual(OrderedDict([
            ('title__name', 'one'),
            ('project__name', 'two'),
        ]), f(['one', 'two']))
Example #18
0
    def setUp(self):
        management.call_command('avocado', 'init', 'tests', quiet=True)

        f1 = DataField.objects.get_by_natural_key('tests', 'employee',
                                                  'first_name')
        f2 = DataField.objects.get_by_natural_key('tests', 'employee',
                                                  'last_name')

        self.c = DataConcept()
        self.c.save()

        DataConceptField(concept=self.c, field=f1).save()
        DataConceptField(concept=self.c, field=f2).save()

        self.request = HttpRequest()
        self.request.session = SessionStore()
        self.request.session.save()
Example #19
0
    def test_dataview_order_by(self):
        f = DataField(app_name='tests', model_name='month', field_name='id')
        f.save()

        c = DataConcept()
        c.save()

        cf = DataConceptField(field=f, concept=c)
        cf.save()

        v = DataView({'ordering': [[c.pk, 'asc']]})

        qs = Month.objects.filter(label__startswith='J').values('id')
        self.assertEqual(
            unicode(v.apply(qs).query),
            'SELECT "tests_month"."id" FROM "tests_month" WHERE "tests_month"."label" LIKE J% ESCAPE \'\\\'  ORDER BY "tests_month"."order" ASC'
        )
Example #20
0
    def test_unique_keys(self):
        title_name = DataField.objects.get_by_natural_key(
            'tests', 'title', 'name')

        project_name = DataField.objects.get_by_natural_key(
            'tests', 'project', 'name')

        concept = DataConcept()
        concept.save()

        DataConceptField(concept=concept, field=title_name, order=1).save()
        DataConceptField(concept=concept, field=project_name, order=2).save()

        f = Formatter(concept=concept)

        meta = f.get_meta()
        names = [x['name'] for x in meta['header']]

        self.assertEqual(names, ['title__name', 'project__name'])
Example #21
0
    def setUp(self):
        management.call_command('avocado', 'init', 'tests', quiet=True)

        name_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'name')
        salary_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'salary')
        boss_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'boss')

        concept = DataConcept(name='Title')
        concept.save()

        DataConceptField(concept=concept, field=name_field, order=1).save()
        DataConceptField(concept=concept, field=salary_field, order=2).save()
        DataConceptField(concept=concept, field=boss_field, order=3).save()

        self.concept = concept
        self.values = ['CEO', 100000, True]
Example #22
0
    def test_unique_keys(self):
        title_name = DataField.objects.get_by_natural_key(
            'tests', 'title', 'name')
        project_name = DataField.objects.get_by_natural_key(
            'tests', 'project', 'name')

        concept = DataConcept()
        concept.save()

        DataConceptField(concept=concept, field=title_name, order=1).save()
        DataConceptField(concept=concept, field=project_name, order=2).save()

        f = Formatter(concept)

        self.assertEqual(
            OrderedDict([
                ('title__name', 'one'),
                ('project__name', 'two'),
            ]), f(['one', 'two']))
Example #23
0
    def test_view(self):
        salary_field = DataField.objects.get_by_natural_key('exporting', 'title', 'salary')
        salary_concept = DataConcept()
        salary_concept.save()
        DataConceptField(concept=salary_concept, field=salary_field, order=1).save()

        view = DataView(json={'ordering': [[salary_concept.pk, 'desc']]})
        query = view.apply(tree=models.Employee).raw()

        # Ick..
        exporter = export.CSVExporter(view)
        exporter.params.insert(0, (RawFormatter(keys=['pk']), 1))
        exporter.row_length += 1

        buff = exporter.write(query)
        buff.seek(0)

        lines = buff.read().splitlines()
        # Skip the header
        self.assertEqual([int(x) for x in lines[1:]], [2, 4, 6, 1, 3, 5])
Example #24
0
    def test_get_all_unrelated(self):
        # Publish unrelated field and concept
        f = DataField.objects.get(model_name='unrelated')
        f.published = True
        f.save()

        c = DataConcept(name='Unrelated', published=True)
        c.save()

        DataConceptField(concept=c, field=f, order=1).save()

        # Concept from two unrelated fields.. this will never show.
        # TODO don't allow this
        c = DataConcept(name='Unrelated', published=True)
        c.save()

        DataConceptField(concept=c, field=f, order=1).save()
        DataConceptField(concept=c, field=self.boss_field, order=2).save()

        # Still 2 concepts visible by default tree
        response = self.client.get('/api/concepts/',
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, codes.ok)
        self.assertEqual(len(json.loads(response.content)), 2)

        # 1 concept visible for unrelated tree
        response = self.client.get('/api/concepts/?tree=unrelated',
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, codes.ok)
        self.assertEqual(len(json.loads(response.content)), 1)
Example #25
0
    def test_published(self):
        concept = DataConcept(published=True)
        concept.save()
        DataConceptField(concept=concept, field=self.is_manager).save()
        DataConceptField(concept=concept, field=self.salary).save()

        self.assertEqual([x.pk for x in DataConcept.objects.published()], [])

        self.is_manager.published = True
        self.is_manager.save()
        self.salary.published = True
        self.salary.save()

        # Now published, it will appear
        self.assertEqual([x.pk for x in DataConcept.objects.published()],
                         [concept.pk])

        # Set the category to be an unpublished category and it should no
        # longer appear.
        concept.category = self.category
        concept.save()
        self.assertEqual([x.pk for x in DataConcept.objects.published()], [])

        # Publish the category and the concept should appear again
        self.category.published = True
        self.category.save()
        self.assertEqual([x.pk for x in DataConcept.objects.published()],
                         [concept.pk])

        user1 = User.objects.create_user('user1', 'user1')

        # Nothing since user1 cannot view either datafield
        self.assertEqual([x.pk for x in DataConcept.objects.published(user1)],
                         [])

        assign('avocado.view_datafield', user1, self.is_manager)
        # Still nothing since user1 has no permission for salary
        self.assertEqual([x.pk for x in DataConcept.objects.published(user1)],
                         [])

        assign('avocado.view_datafield', user1, self.salary)
        # Now user1 can see the concept
        self.assertEqual([x.pk for x in DataConcept.objects.published(user1)],
                         [concept.pk])

        user2 = User.objects.create_user('user2', 'user2')

        # `user2` is not assigned
        self.assertEqual([x.pk for x in DataConcept.objects.published(user2)],
                         [])

        # Remove the fields from the concept and it should no longer appear
        # as published.
        DataConceptField.objects.filter(concept=concept).delete()
        self.assertEqual([x.pk for x in DataConcept.objects.published()], [])
Example #26
0
class BaseTestCase(TestCase):
    fixtures = ['tests/fixtures/test_data.json']

    def setUp(self):
        management.call_command('avocado', 'init', 'tests', quiet=True)

        f1 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'first_name')
        f2 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'last_name')

        self.c = DataConcept()
        self.c.save()

        DataConceptField(concept=self.c, field=f1).save()
        DataConceptField(concept=self.c, field=f2).save()

        self.request = HttpRequest()
        self.request.session = SessionStore()
        self.request.session.save()
Example #27
0
    def test_published(self):
        concept = DataConcept(published=True)
        concept.save()
        DataConceptField(concept=concept, field=self.is_manager).save()
        DataConceptField(concept=concept, field=self.salary).save()

        self.assertEqual([x.pk for x in DataConcept.objects.published()], [])

        self.is_manager.published = True
        self.is_manager.save()
        self.salary.published = True
        self.salary.save()

        # Now published, it will appear
        self.assertEqual([x.pk for x in DataConcept.objects.published()],
                         [concept.pk])

        # Set the category to be an unpublished category and it should no
        # longer appear.
        concept.category = self.category
        concept.save()
        self.assertEqual([x.pk for x in DataConcept.objects.published()], [])

        # Publish the category and the concept should appear again
        self.category.published = True
        self.category.save()
        self.assertEqual([x.pk for x in DataConcept.objects.published()],
                         [concept.pk])

        user1 = User.objects.create_user('user1', 'user1')

        # Nothing since user1 cannot view either datafield
        self.assertEqual(
            [x.pk for x in DataConcept.objects.published(user1)], [])

        assign('avocado.view_datafield', user1, self.is_manager)
        # Still nothing since user1 has no permission for salary
        self.assertEqual(
            [x.pk for x in DataConcept.objects.published(user1)], [])

        assign('avocado.view_datafield', user1, self.salary)
        # Now user1 can see the concept
        self.assertEqual([x.pk for x in DataConcept.objects.published(user1)],
                         [concept.pk])

        user2 = User.objects.create_user('user2', 'user2')

        # `user2` is not assigned
        self.assertEqual(
            [x.pk for x in DataConcept.objects.published(user2)], [])

        # Remove the fields from the concept and it should no longer appear
        # as published.
        DataConceptField.objects.filter(concept=concept).delete()
        self.assertEqual([x.pk for x in DataConcept.objects.published()], [])
    def setUp(self):
        management.call_command('avocado', 'sync', 'openmrs')

        birthdate_field = DataField.objects.get_by_natural_key(
            'openmrs', 'patient', 'birthdate')
        estimate_field = DataField.objects.get_by_natural_key(
            'openmrs', 'patient', 'birthdate_estimated')

        self.concept = concept = DataConcept(name="Birthdate")
        concept.save()

        DataConceptField(concept=concept, field=birthdate_field,
                         order=1).save()
        DataConceptField(concept=concept, field=estimate_field, order=2).save()

        formatter = registry.get('Age')
        self.f = formatter(concept)
Example #29
0
    def setUp(self):
        management.call_command('avocado', 'init', 'tests', quiet=True)

        first_name_field = DataField.objects.get_by_natural_key(
            'tests', 'employee', 'first_name')
        first_name_field.description = 'First Name'
        first_name_field.save()

        last_name_field = DataField.objects.get_by_natural_key(
            'tests', 'employee', 'last_name')
        last_name_field.description = 'Last Name'
        last_name_field.save()

        title_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'name')
        title_field.description = 'Employee Title'
        title_field.save()

        salary_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'salary')
        salary_field.description = 'Salary'
        salary_field.save()

        is_manager_field = DataField.objects.get_by_natural_key(
            'tests', 'employee', 'is_manager')
        is_manager_field.description = 'Is a Manager?'
        is_manager_field.save()

        employee_concept = DataConcept()
        employee_concept.name = 'Employee'
        employee_concept.description = 'A Single Employee'
        employee_concept.save()

        DataConceptField(concept=employee_concept,
                         field=first_name_field,
                         order=1).save()
        DataConceptField(concept=employee_concept,
                         field=last_name_field,
                         order=2).save()
        DataConceptField(concept=employee_concept,
                         field=is_manager_field,
                         order=3).save()
        DataConceptField(concept=employee_concept, field=title_field,
                         order=4).save()
        DataConceptField(concept=employee_concept, field=salary_field,
                         order=5).save()

        self.concepts = [employee_concept]

        self.query = models.Employee.objects.values_list(
            'first_name', 'last_name', 'is_manager', 'title__name',
            'title__salary')
Example #30
0
    def test_format(self):
        name_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'name')
        salary_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'salary')
        boss_field = DataField.objects.get_by_natural_key(
            'tests', 'title', 'boss')

        concept = DataConcept(name='Title')
        concept.save()

        DataConceptField(concept=concept, field=name_field, order=1).save()
        DataConceptField(concept=concept, field=salary_field, order=2).save()
        DataConceptField(concept=concept, field=boss_field, order=3).save()

        values = ['CEO', 100000, True]

        self.assertEqual(
            concept.format(values),
            OrderedDict([(u'name', u'CEO'), (u'salary', 100000),
                         (u'boss', True)]))

        self.assertEqual(concept._formatter_cache[0], None)

        from avocado.formatters import Formatter, registry as formatters

        class HtmlFormatter(Formatter):
            def to_html(self, values, **context):
                fvalues = self(values, preferred_formats=['string'])
                return OrderedDict({
                    'profile':
                    '<span>' + '</span><span>'.join(fvalues.values()) +
                    '</span>'
                })

            to_html.process_multiple = True

        formatters.register(HtmlFormatter, 'HTML')
        concept.formatter_name = 'HTML'

        self.assertEqual(
            concept.format(values, preferred_formats=['html']),
            OrderedDict([
                ('profile',
                 u'<span>CEO</span><span>100000</span><span>True</span>')
            ]))
Example #31
0
    def test_format(self):
        name_field = DataField.objects.get_by_natural_key('models', 'title', 'name')
        salary_field = DataField.objects.get_by_natural_key('models', 'title', 'salary')
        boss_field = DataField.objects.get_by_natural_key('models', 'title', 'boss')

        concept = DataConcept(name='Title')
        concept.save()

        DataConceptField(concept=concept, field=name_field, order=1).save()
        DataConceptField(concept=concept, field=salary_field, order=2).save()
        DataConceptField(concept=concept, field=boss_field, order=3).save()

        values = ['CEO', 100000, True]

        self.assertEqual(concept.format(values),
            OrderedDict([
                (u'name', u'CEO'),
                (u'salary', 100000),
                (u'boss', True)
            ]))

        self.assertEqual(concept._formatter_cache[0], None)

        from avocado.formatters import Formatter, registry as formatters

        class HtmlFormatter(Formatter):
            def to_html(self, values, **context):
                fvalues = self(values, preferred_formats=['string'])
                return OrderedDict({
                    'profile': '<span>' + '</span><span>'.join(fvalues.values()) + '</span>'
                })
            to_html.process_multiple = True

        formatters.register(HtmlFormatter, 'HTML')
        concept.formatter_name = 'HTML'

        self.assertEqual(concept.format(values, preferred_formats=['html']),
            OrderedDict([
                ('profile', u'<span>CEO</span><span>100000</span><span>True</span>')
            ]))
Example #32
0
    def test_field_for_concept(self):
        f = DataField.objects.get(id=4)
        c1 = DataConcept()
        c2 = DataConcept()
        c1.save()
        c2.save()
        cf = DataConceptField(concept=c1, field=f)
        cf.save()

        self.assertEqual(parsers.datacontext.validate({
            'concept': c1.pk,
            'field': 4,
            'operator': 'exact',
            'value': 'CEO'
        }, tree=Employee), None)

        # Invalid concept
        self.assertRaises(ValidationError, parsers.datacontext.validate, {
            'concept': c2.pk,
            'field': 4,
            'operator': 'exact',
            'value': 'CEO'
        }, tree=Employee)
Example #33
0
 def setUp(self):
     super(FieldValidatorTestCase, self).setUp()
     self.field = DataField.objects.get_by_natural_key('tests.title.salary')
     self.concept = DataConcept(name='Salary', ident='salary')
     self.concept.save()
     DataConceptField(concept=self.concept, field=self.field).save()
Example #34
0
class FieldValidatorTestCase(ValidatorTestCase):
    def setUp(self):
        super(FieldValidatorTestCase, self).setUp()
        self.field = DataField.objects.get_by_natural_key('tests.title.salary')
        self.concept = DataConcept(name='Salary', ident='salary')
        self.concept.save()
        DataConceptField(concept=self.concept, field=self.field).save()

    def test_valid_field_nk(self):
        "Field with natural key"
        data = {
            'field': 'tests.title.salary',
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)

    def test_valid_field_nk_list(self):
        "Field with list-based natural key"
        data = {
            'field': ['tests', 'title', 'salary'],
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)

    def test_valid_field_pk(self):
        "Field with primary key"
        data = {
            'field': self.field.pk,
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)

    def test_valid_concept(self):
        "Field with concept primary key"
        data = {
            'field': self.field.pk,
            'concept': self.concept.pk,
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)
        self.assertEqual(v.cleaned_data['concept'], self.concept)

    def test_valid_concept_ident(self):
        "Field with concept ident"
        data = {
            'field': self.field.pk,
            'concept': 'salary',
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)
        self.assertEqual(v.cleaned_data['concept'], self.concept)

    def test_valid_concept_short_field(self):
        "Field short name with concept"
        data = {
            'field': 'salary',
            'concept': self.concept.pk,
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)
        self.assertEqual(v.cleaned_data['concept'], self.concept)

    def test_invalid_field(self):
        "Field does not exist"
        v = FieldValidator({
            'field': 'invalid.lookup',
        })

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'field_does_not_exist')
        self.assertFalse(v.data['enabled'])

    def test_invalid_concept(self):
        "Concept does not exist"
        v = FieldValidator({
            'field': self.field.pk,
            'concept': 'does_not_exist',
        })

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'concept_does_not_exist')
        self.assertFalse(v.data['enabled'])

    def test_invalid_field_for_concept(self):
        "Field not contained in concept"
        v = FieldValidator({
            'field': 'tests.title.name',
            'concept': self.concept.pk,
        })

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'field_does_not_exist_for_concept')
        self.assertFalse(v.data['enabled'])

    def test_ambiguous_field(self):
        "Ambiguous field"
        # Could be the name for salary or project..
        v = FieldValidator({
            'field': 'name'
        })

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'ambiguous_field')
        self.assertFalse(v.data['enabled'])
Example #35
0
    def test_get_all_category_sort(self):
        # Create some temporary concepts and categories
        cat1 = DataCategory(name='Category1', order=1.0, published=True)
        cat1.save()

        c1 = DataConcept(name='B', published=True, category=cat1)
        c1.save()
        field1 = DataConceptField(concept=c1, field=self.name_field, order=1)
        field1.save()

        c2 = DataConcept(name='C', published=True, category=cat1)
        c2.save()
        field2 = DataConceptField(concept=c2, field=self.name_field, order=1)
        field2.save()

        c3 = DataConcept(name='A', published=True, category=cat1)
        c3.save()
        field3 = DataConceptField(concept=c3, field=self.name_field, order=1)
        field3.save()

        # Check that category ordering is happening by default
        response = self.client.get('/api/concepts/',
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['Title', 'Name', 'B', 'C', 'A'])

        # Reverse the ordering of the categories
        response = self.client.get('/api/concepts/',
                                   {'order': 'desc'},
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['B', 'C', 'A', 'Title', 'Name'])

        # Order by concept name in addition to category
        response = self.client.get('/api/concepts/',
                                   {'sort': 'name'},
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['Name', 'Title', 'A', 'B', 'C'])

        # Reverse the name and category sorting
        response = self.client.get('/api/concepts/',
                                   {'sort': 'name', 'order': 'desc'},
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['C', 'B', 'A', 'Title', 'Name'])

        c1.delete()
        c2.delete()
        c3.delete()
        field1.delete()
        field2.delete()
        field3.delete()
        cat1.delete()
Example #36
0
class FieldValidatorTestCase(ValidatorTestCase):
    def setUp(self):
        super(FieldValidatorTestCase, self).setUp()
        self.field = DataField.objects.get_by_natural_key('tests.title.salary')
        self.concept = DataConcept(name='Salary')
        self.concept.save()
        DataConceptField(concept=self.concept, field=self.field).save()

    def test_valid_field_nk(self):
        "Field with natural key"
        data = {
            'field': 'tests.title.salary',
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)

    def test_valid_field_nk_list(self):
        "Field with list-based natural key"
        data = {
            'field': ['tests', 'title', 'salary'],
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)

    def test_valid_field_pk(self):
        "Field with primary key"
        data = {
            'field': self.field.pk,
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)

    def test_valid_concept(self):
        "Field with concept primary key"
        data = {
            'field': self.field.pk,
            'concept': self.concept.pk,
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)
        self.assertEqual(v.cleaned_data['concept'], self.concept)

    def test_valid_concept_ident(self):
        "Field with concept ident"
        data = {
            'field': self.field.pk,
            'concept': 'salary',
        }

        v = FieldValidator(data)

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'concept_wrong_format')
        self.assertFalse(v.data['enabled'])

    def test_valid_concept_short_field(self):
        "Field short name with concept"
        data = {
            'field': 'salary',
            'concept': self.concept.pk,
        }

        v = FieldValidator(data)

        self.assertTrue(v.is_valid())
        self.assertEqual(v.data, data)
        self.assertEqual(v.cleaned_data['field'], self.field)
        self.assertEqual(v.cleaned_data['concept'], self.concept)

    def test_invalid_field(self):
        "Field does not exist"
        v = FieldValidator({
            'field': 'invalid.lookup',
        })

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'field_does_not_exist')
        self.assertFalse(v.data['enabled'])

    def test_invalid_concept(self):
        "Concept does not exist"
        v = FieldValidator({
            'field': self.field.pk,
            'concept': -1,
        })

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'concept_does_not_exist')
        self.assertFalse(v.data['enabled'])

    def test_invalid_field_for_concept(self):
        "Field not contained in concept"
        v = FieldValidator({
            'field': 'tests.title.name',
            'concept': self.concept.pk,
        })

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'field_does_not_exist_for_concept')
        self.assertFalse(v.data['enabled'])

    def test_ambiguous_field(self):
        "Ambiguous field"
        # Could be the name for salary or project..
        v = FieldValidator({'field': 'name'})

        self.assertFalse(v.is_valid())
        self.assertTrue('errors' in v.data)
        self.assertEqual(v.errors[0], 'ambiguous_field')
        self.assertFalse(v.data['enabled'])
Example #37
0
 def setUp(self):
     super(FieldValidatorTestCase, self).setUp()
     self.field = DataField.objects.get_by_natural_key('tests.title.salary')
     self.concept = DataConcept(name='Salary')
     self.concept.save()
     DataConceptField(concept=self.concept, field=self.field).save()
Example #38
0
    def test_get_all_category_sort(self):
        # Create some temporary concepts and categories.
        cat1 = DataCategory(name='Category1', order=2.0, published=True)
        cat1.save()

        c1 = DataConcept(name='B', published=True, category=cat1, order=1)
        c1.save()
        field1 = DataConceptField(concept=c1, field=self.name_field, order=1)
        field1.save()

        c2 = DataConcept(name='C', published=True, category=cat1, order=2)
        c2.save()
        field2 = DataConceptField(concept=c2, field=self.name_field, order=1)
        field2.save()

        c3 = DataConcept(name='A', published=True, category=cat1, order=3)
        c3.save()
        field3 = DataConceptField(concept=c3, field=self.name_field, order=1)
        field3.save()

        # Check that category ordering is happening by default.
        response = self.client.get('/api/concepts/',
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, codes.ok)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['Title', 'Name', 'B', 'C', 'A'])

        # Reverse the ordering of the categories.
        response = self.client.get('/api/concepts/',
                                   {'order': 'desc'},
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, codes.ok)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['B', 'C', 'A', 'Title', 'Name'])

        # Order by concept name in addition to category.
        response = self.client.get('/api/concepts/',
                                   {'sort': 'name'},
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, codes.ok)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['Name', 'Title', 'A', 'B', 'C'])

        # Reverse the name and category sorting.
        response = self.client.get('/api/concepts/',
                                   {'sort': 'name', 'order': 'desc'},
                                   HTTP_ACCEPT='application/json')
        self.assertEqual(response.status_code, codes.ok)
        self.assertEqual(len(json.loads(response.content)), 5)
        names = [concept.get('name', '') for concept in
                 json.loads(response.content)]
        self.assertEqual(names, ['C', 'B', 'A', 'Title', 'Name'])

        c1.delete()
        c2.delete()
        c3.delete()
        field1.delete()
        field2.delete()
        field3.delete()
        cat1.delete()
Example #39
0
    def _migrate_concept(self, model, migrate_func, **options):
        no_input = options.get('no_input')

        total_migrated = 0

        for lc in model.objects.iterator():
            field_nks = list(lc.fields.values('app_name', 'model_name',
                                              'field_name').distinct())
            field_cond = Q()

            for f in field_nks:
                field_cond = field_cond | Q(**f)

            fields = DataField.objects.filter(field_cond).distinct()

            # Mismatch of fields from new to old
            if len(fields) != len(field_nks):
                print('One or more fields mismatched for "{0}". '
                      'Skipping...'.format(lc))
                continue

            matches = DataConcept.objects.filter(name=lc.name)

            # Filter concepts by existence of fields
            for f in fields:
                matches = matches.filter(fields__app_name=f.app_name,
                                         fields__model_name=f.model_name,
                                         fields__field_name=f.field_name)

            num = len(matches)

            if num > 1:
                print('{0} have the same name and fields. '
                      'Skipping...'.format(num))
                continue

            if num == 1:
                c = matches[0]
                existing = True

                if not no_input:
                    override = True
                    while True:
                        response = raw_input(u'Match found for "{0}". '
                                             'Override? [n/Y] '.format(c))
                        if not response:
                            break
                        if response.lower() == 'n':
                            override = False
                            break
                    if not override:
                        continue
            else:
                c = DataConcept(queryable=False, viewable=False)
                existing = False

            c.name = lc.name
            c.order = lc.order
            c.published = lc.is_public

            # This looks odd, but this handles choosing the longer of the two
            # descriptions for criterion and column if both exist.
            if not c.description or lc.description and \
                    len(lc.description) > len(c.description):
                c.description = lc.description

            if lc.category:
                try:
                    kwargs = {
                        'name__iexact': lc.category.name,
                    }
                    # Filter by parent if one exists since categories with the
                    # same name can exists as sub-categories.
                    if lc.category.parent_id:
                        kwargs['parent__name'] = lc.category.parent.name
                    c.category = DataCategory.objects.get(**kwargs)
                except DataCategory.DoesNotExist:
                    pass

            # Apply migration specific function to concept from legacy concept
            migrate_func(c, lc)

            # Save for foreign key references to concept fields
            c.save()

            cfs = []

            if not existing:
                lcfs = list(lc.conceptfields.select_related('field'))

                # Dict of legacy concept fields to the new field it
                # corresponds to
                lcf_map = {}

                for lcf in lcfs:
                    for f in fields:
                        # Match and break
                        if lcf.field.natural_key() == f.natural_key():
                            lcf_map[lcf.pk] = f
                            break

                # Map fields to
                # Iterate over all legacy concept fields and create the new
                # concept fields
                for lcf in lcfs:
                    f = lcf_map[lcf.pk]
                    cfs.append(DataConceptField(concept=c, field=f,
                                                name=lcf.name,
                                                order=lcf.order))

            # Save concept fields
            for cf in cfs:
                cf.save()

            print 'Migrated "{0}"'.format(c)
            total_migrated += 1

        print '{0} migrated: {1}'.format(model.__name__, total_migrated)
Example #40
0
class DataViewParserTestCase(TestCase):
    fixtures = ['tests/fixtures/employee_data.json']

    def setUp(self):
        management.call_command('avocado', 'init', 'tests', publish=False,
                                concepts=False, quiet=True)
        f1 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'first_name')
        f2 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'last_name')

        self.c = DataConcept()
        self.c.save()

        DataConceptField(concept=self.c, field=f1).save()
        DataConceptField(concept=self.c, field=f2).save()

    def test_valid(self):
        # Single by id
        self.assertEqual(parsers.dataview.validate([{
            'concept': self.c.pk
        }], tree=Employee), [{
            'concept': self.c.pk,
        }])

        self.assertEqual(parsers.dataview.validate([{
            'concept': self.c.pk,
            'sort': 'desc',
        }], tree=Employee), [{
            'concept': self.c.pk,
            'sort': 'desc',
        }])

    def test_valid_legacy(self):
        # Single by id
        self.assertEqual(parsers.dataview.validate({
            'columns': [self.c.pk],
        }, tree=Employee), [{
            'concept': self.c.pk,
            'visible': True,
            'sort': None,
            'sort_index': None,
        }])

        self.assertEqual(parsers.dataview.validate({
            'ordering': [(self.c.pk, 'desc')],
        }, tree=Employee), [{
            'concept': self.c.pk,
            'visible': False,
            'sort': 'desc',
            'sort_index': 0,
        }])

    def test_invalid(self):
        # Non-existent data field
        facets = parsers.dataview.validate({'columns': [999]})
        self.assertFalse(facets[0]['enabled'])
        self.assertTrue(facets[0]['errors'])

        # Invalid ordering
        facets = parsers.dataview.validate([{
            'concept': self.c.pk,
            'sort': 'foo',
        }])
        self.assertTrue(facets[0]['warnings'])

    def test_apply(self):
        node = parsers.dataview.parse([{
            'concept': self.c.pk,
        }], tree=Employee)

        self.assertEqual(
            unicode(node.apply().query).replace(' ', ''),
            'SELECT "tests_employee"."id", "tests_employee"."first_name", '
            '"tests_employee"."last_name" FROM "tests_employee"'
            .replace(' ', ''))

        node = parsers.dataview.parse([{
            'concept': self.c.pk,
            'sort': 'desc',
            'visible': False,
        }], tree=Employee)

        self.assertEqual(
            unicode(node.apply().query).replace(' ', ''),
            'SELECT "tests_employee"."id" FROM "tests_employee" '
            'ORDER BY "tests_employee"."first_name" DESC, '
            '"tests_employee"."last_name" DESC'
            .replace(' ', ''))

    def test_apply_distinct(self):
        node = parsers.dataview.parse([{
            'concept': self.c.pk,
        }], tree=Employee)

        self.assertEqual(
            unicode(node.apply(Employee.objects.distinct()).query)
            .replace(' ', ''),
            'SELECT DISTINCT "tests_employee"."id", '
            '"tests_employee"."first_name", '
            '"tests_employee"."last_name" FROM "tests_employee"'
            .replace(' ', ''))

    def test_implicit_apply_distinct(self):
        f1 = DataField.objects.get_by_natural_key('tests',
                                                  'office',
                                                  'location')
        f2 = DataField.objects.get_by_natural_key('tests',
                                                  'title',
                                                  'name')
        c = DataConcept()
        c.save()

        DataConceptField(concept=c, field=f1).save()
        DataConceptField(concept=c, field=f2).save()

        # Due to the use of distinct, the concept fields appear in the SELECT
        # statement at this point. This is not a bug, but a requirement of SQL.
        # These columns are stripped downstream by the exporter.
        node = parsers.dataview.parse([{
            'concept': c.pk,
            'sort': 'desc',
            'visible': False,
        }], tree=Employee)

        self.assertEqual(
            unicode(node.apply(Employee.objects.distinct()).query)
            .replace(' ', ''),
            'SELECT DISTINCT "tests_employee"."id", '
            '"tests_office"."location", "tests_title"."name" FROM '
            '"tests_employee" INNER JOIN "tests_office" ON '
            '("tests_employee"."office_id" = "tests_office"."id") LEFT OUTER '
            'JOIN "tests_title" ON ("tests_employee"."title_id" = '
            '"tests_title"."id") ORDER BY "tests_office"."location" DESC, '
            '"tests_title"."name" DESC'
            .replace(' ', ''))
Example #41
0
class DataQueryParserTestCase(TestCase):
    fixtures = ['employee_data.json']

    def setUp(self):
        management.call_command('avocado', 'init', 'tests', publish=False,
                                concepts=False, quiet=True)
        f1 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'first_name')
        f2 = DataField.objects.get_by_natural_key('tests',
                                                  'employee',
                                                  'last_name')

        self.c = DataConcept()
        self.c.save()

        DataConceptField(concept=self.c, field=f1).save()
        DataConceptField(concept=self.c, field=f2).save()

    def test_valid(self):
        self.assertEqual(parsers.dataquery.validate({}, tree=Employee), None)

        attrs = {
            'context': {
                'field': 'tests.title.name',
                'operator': 'exact',
                'value': 'CEO',
                'cleaned_value': {'value': 'CEO', 'label': 'CEO'},
                'language': 'Name is CEO'
            },
            'view': [{
                'concept': self.c.pk,
            }],
        }

        exp_attrs = deepcopy(attrs)

        self.assertEqual(parsers.dataquery.validate(attrs, tree=Employee),
                         exp_attrs)

        # Only the context
        attrs = {
            'context': {
                'field': 'tests.title.name',
                'operator': 'exact',
                'value': 'CEO',
                'cleaned_value': {
                    'value': 'CEO',
                    'label': 'CEO',
                },
                'language': 'Name is CEO'
            }
        }

        exp_attrs = deepcopy(attrs)
        exp_attrs['view'] = None

        self.assertEqual(parsers.dataquery.validate(attrs, tree=Employee),
                         exp_attrs)

        # Only the view
        attrs = {
            'view': [{
                'concept': self.c.pk,
                'visible': False,
                'sort': 'desc',
            }]
        }

        exp_attrs = {
            'context': None,
            'view': [{
                'visible': False,
                'concept': self.c.pk,
                'sort': 'desc',
            }],
        }
        self.assertEqual(parsers.dataquery.validate(attrs, tree=Employee),
                         exp_attrs)

    def test_parsed_node(self):
        # Make sure no context or view subnodes are created
        node = parsers.dataquery.parse({}, tree=Employee)
        self.assertEqual(node.datacontext_node, None)
        self.assertEqual(node.dataview_node, None)

        node = parsers.dataquery.parse({
            'context': {
                'type': 'and',
                'children': [],
            }
        }, tree=Employee)

        # No condition has been defined..
        self.assertEqual(node.datacontext_node.condition, None)

        node = parsers.dataquery.parse({
            'context': {
                'type': 'and',
                'children': [{
                    'field': 'tests.title.name',
                    'operator': 'exact',
                    'value': 'CEO',
                }]
            }
        }, tree=Employee)

        # Only the one condition is represented
        self.assertEqual(str(node.datacontext_node.condition),
                         "(AND: ('title__name__exact', u'CEO'))")

    def test_apply(self):
        node = parsers.dataquery.parse({
            'context': {
                'field': 'tests.title.boss',
                'operator': 'exact',
                'value': True
            },
            'view': [{
                'concept': self.c.pk,
            }],
        }, tree=Employee)

        self.assertEqual(
            unicode(node.apply().query).replace(' ', ''),
            'SELECT DISTINCT "tests_employee"."id", '
            '"tests_employee"."first_name", "tests_employee"."last_name" FROM '
            '"tests_employee" INNER JOIN "tests_title" ON '
            '("tests_employee"."title_id" = "tests_title"."id") '
            'WHERE "tests_title"."boss" = True '
            .replace(' ', ''))

        # Just the view
        node = parsers.dataquery.parse({
            'view': [{
                'concept': self.c.pk,
                'sort': 'desc',
            }]
        }, tree=Employee)

        self.assertEqual(
            unicode(node.apply().query).replace(' ', ''),
            'SELECT DISTINCT "tests_employee"."id", '
            '"tests_employee"."first_name", '
            '"tests_employee"."last_name" FROM "tests_employee" '
            'ORDER BY "tests_employee"."first_name" DESC, '
            '"tests_employee"."last_name" DESC'.replace(' ', ''))

        # Just the context
        node = parsers.dataquery.parse({
            'context': {
                'field': 'tests.title.boss',
                'operator': 'exact',
                'value': True
            }
        }, tree=Employee)

        self.assertEqual(
            unicode(node.apply().values('id').query).replace(' ', ''),
            'SELECT DISTINCT "tests_employee"."id" FROM "tests_employee" '
            'INNER JOIN "tests_title" ON ("tests_employee"."title_id" = '
            '"tests_title"."id") WHERE "tests_title"."boss" = True '
            .replace(' ', ''))

        f = DataField.objects.get_by_natural_key('tests', 'title', 'boss')
        self.assertEqual(node.datacontext_node.language, {
            'operator': 'exact',
            'language': u'Boss is True',
            'field': f.pk,
            'value': True
        })
Example #42
0
    def _migrate_concept(self, model, migrate_func, **options):
        no_input = options.get('no_input')

        total_migrated = 0

        for lc in model.objects.iterator():
            field_nks = list(
                lc.fields.values('app_name', 'model_name',
                                 'field_name').distinct())
            field_cond = Q()

            for f in field_nks:
                field_cond = field_cond | Q(**f)

            fields = DataField.objects.filter(field_cond).distinct()

            # Mismatch of fields from new to old
            if len(fields) != len(field_nks):
                print(
                    'One or more fields mismatched for "{0}". '
                    'Skipping...'.format(lc))
                continue

            matches = DataConcept.objects.filter(name=lc.name)

            # Filter concepts by existence of fields
            for f in fields:
                matches = matches.filter(fields__app_name=f.app_name,
                                         fields__model_name=f.model_name,
                                         fields__field_name=f.field_name)

            num = len(matches)

            if num > 1:
                print('{0} have the same name and fields. '
                      'Skipping...'.format(num))
                continue

            if num == 1:
                c = matches[0]
                existing = True

                if not no_input:
                    override = True
                    while True:
                        response = raw_input(u'Match found for "{0}". '
                                             'Override? [n/Y] '.format(c))
                        if not response:
                            break
                        if response.lower() == 'n':
                            override = False
                            break
                    if not override:
                        continue
            else:
                c = DataConcept(queryable=False, viewable=False)
                existing = False

            c.name = lc.name
            c.order = lc.order
            c.published = lc.is_public

            # This looks odd, but this handles choosing the longer of the two
            # descriptions for criterion and column if both exist.
            if not c.description or lc.description and \
                    len(lc.description) > len(c.description):
                c.description = lc.description

            if lc.category:
                try:
                    kwargs = {
                        'name__iexact': lc.category.name,
                    }
                    # Filter by parent if one exists since categories with the
                    # same name can exists as sub-categories.
                    if lc.category.parent_id:
                        kwargs['parent__name'] = lc.category.parent.name
                    c.category = DataCategory.objects.get(**kwargs)
                except DataCategory.DoesNotExist:
                    pass

            # Apply migration specific function to concept from legacy concept
            migrate_func(c, lc)

            # Save for foreign key references to concept fields
            c.save()

            cfs = []

            if not existing:
                lcfs = list(lc.conceptfields.select_related('field'))

                # Dict of legacy concept fields to the new field it
                # corresponds to
                lcf_map = {}

                for lcf in lcfs:
                    for f in fields:
                        # Match and break
                        if lcf.field.natural_key() == f.natural_key():
                            lcf_map[lcf.pk] = f
                            break

                # Map fields to
                # Iterate over all legacy concept fields and create the new
                # concept fields
                for lcf in lcfs:
                    f = lcf_map[lcf.pk]
                    cfs.append(
                        DataConceptField(concept=c,
                                         field=f,
                                         name=lcf.name,
                                         order=lcf.order))

            # Save concept fields
            for cf in cfs:
                cf.save()

            print 'Migrated "{0}"'.format(c)
            total_migrated += 1

        print '{0} migrated: {1}'.format(model.__name__, total_migrated)