예제 #1
0
    def test_filter_by_tags_and(self):
        """Show only commrec with correct tags in 'and' configuration."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])
            ])), [])
        subjects = {r['subject'] for r in recs}
        expected = set()
        self.assertEqual(expected, subjects)

        # Now try adding another tag.
        self.record_1.tags.add(self.west_tag)
        self.record_1.save()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])
            ])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)
    def test_filter_by_tags_and(self):
        """
        Show only contact with correct tags in 'and' configuration.

        """
        ds = ContactsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            ContactsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])
            ])), [])
        names = {r['name'] for r in recs}
        expected = set()
        self.assertEqual(expected, names)

        # Now try adding another tag.
        self.john.tags.add(self.west_tag)
        recs = ds.run_unaggregated(
            self.company,
            ContactsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])
            ])), [])
        names = {r['name'] for r in recs}
        expected = {self.john.name}
        self.assertEqual(expected, names)
 def test_tag_filter(self):
     """Test that tag filter is built properly."""
     result = self.driver.build_filter('{"tags": [[1, 2], [3, 4]]}')
     self.assertEquals(
         ContactsFilter(tags=AndGroupFilter([
             OrGroupFilter([MatchFilter(1), MatchFilter(2)]),
             OrGroupFilter([MatchFilter(3), MatchFilter(4)]),
         ])), result)
예제 #4
0
 def test_clone_without_full(self):
     """Cloning should remove certain fields."""
     filter = PartnersFilter(tags=AndGroupFilter(
         [OrGroupFilter([MatchFilter('C')])]),
                             locations=CompositeAndFilter({
                                 'city':
                                 MatchFilter('A'),
                                 'state':
                                 MatchFilter('B')
                             }))
     expected_with_city = PartnersFilter(
         tags=AndGroupFilter([OrGroupFilter([MatchFilter('C')])]),
         locations=CompositeAndFilter({'city': MatchFilter('A')}))
     expected_with_state = PartnersFilter(
         tags=AndGroupFilter([OrGroupFilter([MatchFilter('C')])]),
         locations=CompositeAndFilter({'state': MatchFilter('B')}))
     self.assertEqual(expected_with_state, filter.clone_without_city())
     self.assertEqual(expected_with_city, filter.clone_without_state())
예제 #5
0
 def test_filter_by_tags_or(self):
     """Show only partner with correct tags in 'or' configuration."""
     ds = PartnersDataSource()
     recs = ds.run_unaggregated(
         self.company,
         PartnersFilter(tags=AndGroupFilter(
             [OrGroupFilter([MatchFilter('EaSt'),
                             MatchFilter('wEsT')])])), [])
     names = {r['name'] for r in recs}
     expected = {self.partner_a.name, self.partner_b.name}
     self.assertEqual(expected, names)
 def test_plain_filter_and(self):
     """Convert AndGroupFilter to plain object."""
     filt = ContactsFilter(tags=AndGroupFilter([
         OrGroupFilter([
             MatchFilter(1),
             MatchFilter(2),
         ]),
         OrGroupFilter([
             MatchFilter(3),
             MatchFilter(4),
         ])
     ]))
     self.assertEqual({'tags': [[1, 2], [3, 4]]}, plain_filter(filt))
    def test_filter_by_partner_tags(self):
        """
        Test that we can filter by partner tags.

        """
        ds = ContactsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            ContactsFilter(partner_tags=AndGroupFilter(
                [OrGroupFilter([MatchFilter('rigHt')])])), [])
        subjects = {r['name'] for r in recs}
        expected = {self.sue.name}
        self.assertEqual(expected, subjects)
예제 #8
0
    def test_filter_by_contact_tags(self):
        """
        Test that we can filter by contact tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(contact_tags=AndGroupFilter(
                [OrGroupFilter([MatchFilter('sOuTh')])])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)
예제 #9
0
    def test_run_count_comm_rec_per_month_no_partners(self):
        """Trip over a bug in the mysql client driver."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for month in [2, 3, 4]:
                self.sue.contactrecord_set.add(
                    ContactRecordFactory(subject=subject,
                                         date_time=datetime(2015, month, 1)))

        ds = PartnersDataSource()
        partners_filter = PartnersFilter(
            tags=AndGroupFilter([OrGroupFilter([MatchFilter('zzz')])]))
        recs = ds.run_count_comm_rec_per_month(self.company, partners_filter,
                                               ['name', 'year', '-month'])
        self.assertEqual(0, len(recs))
    def test_filter_by_tags(self):
        """
        Should show only contact with correct tags.

        """
        ds = ContactsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            ContactsFilter(
                tags=AndGroupFilter([OrGroupFilter([MatchFilter('EaSt')])])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.john.name}
        self.assertEqual(expected, names)
예제 #11
0
 def test_run_count_comm_rec_per_month_empty_partner(self):
     """One partner, no communication records."""
     ds = PartnersDataSource()
     partners_filter = PartnersFilter(
         tags=AndGroupFilter([OrGroupFilter([MatchFilter('east')])]))
     recs = ds.run_count_comm_rec_per_month(self.company, partners_filter,
                                            ['name', 'year', '-month'])
     data = [(r['name'], r['year'], r['month'], r['comm_rec_count'])
             for r in recs]
     self.assertEqual(12, len(data))
     default_year = datetime.now().year
     for item in data:
         self.assertEqual(default_year, item[1])
         self.assertEqual(0, item[3])
예제 #12
0
    def test_filter_by_tags(self):
        """
        Show only commrec with correct tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                tags=AndGroupFilter([OrGroupFilter([MatchFilter('EaSt')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject, self.record_2.subject}
        self.assertEqual(expected, subjects)
예제 #13
0
 def test_and_group(self):
     """Test adorning an AndGroupFilter."""
     self.maxDiff = 10000
     result = adorn_filter(
         None, self.ds,
         ContactsFilter(tags=AndGroupFilter([
             OrGroupFilter([
                 MatchFilter('a'),
                 MatchFilter('c'),
             ]),
             OrGroupFilter([
                 MatchFilter('b'),
                 MatchFilter('d'),
             ]),
         ])))
     self.assertEqual([{
         'tags': ['a', 'c', 'b', 'd'],
     }], self.ds.adorn_calls)
     self.assertEqual(
         ContactsFilter(tags=AndGroupFilter([
             OrGroupFilter([
                 MatchFilter({
                     'value': 'a',
                     'display': 'A',
                     'hexcolor': 'aaaaaa'
                 }),
                 MatchFilter('c')
             ]),
             OrGroupFilter([
                 MatchFilter({
                     'value': 'b',
                     'display': 'B',
                     'hexcolor': 'bbbbbb'
                 }),
                 MatchFilter('d')
             ])
         ])), result)
예제 #14
0
 def test_and_group(self):
     """And group should result in a series of comparisons."""
     qs = MockQuerySet()
     result = apply_filter_to_queryset(
         qs,
         AndGroupFilter([
             OrGroupFilter([MatchFilter('f')]),
             OrGroupFilter([MatchFilter('g'),
                            MatchFilter('h')]),
             MatchFilter('i')
         ]), 'z')
     self.assert_filters_equals([
         Q(z='f'),
         Q(z='g') | Q(z='h'),
         Q(z='i'),
     ], result.filters)
예제 #15
0
    def test_run_count_comm_rec_per_month_one_partner(self):
        """Trip over a bug in the mysql client driver."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for year in [2013, 2015, 2014]:
                for month in [2, 3, 4]:
                    self.sue.contactrecord_set.add(
                        ContactRecordFactory(subject=subject,
                                             date_time=datetime(
                                                 year, month, 1)))

        ds = PartnersDataSource()
        partners_filter = PartnersFilter(
            tags=AndGroupFilter([OrGroupFilter([MatchFilter('west')])]))
        recs = ds.run_count_comm_rec_per_month(self.company, partners_filter,
                                               ['name', 'year', '-month'])
        data = [(r['name'], r['year'], r['month'], r['comm_rec_count'])
                for r in recs]
        self.assertEqual(36, len(data))
예제 #16
0
    def build_filter(self, filter_json):
        """
        Build a filter for the given filter_json

        filters look like: {
            filter_column1: some filter_spec...,
            filter_column2: another filter_spec...,

        }

        filter_specs can be any of:

        missing/null/[]: Empty lists, nulls, or missing keys are all
            interpreted as do not filter on this column.

        [date, date]: A list of two dates is date range. The filter
            class must have a key type of 'date'.

        1/"a": A single choice.

        [1, 2, 3]: A list of choices is an "or group". Match any of the
            choices.

        [[1, 2, 3], [4, 5, 6]]: A list of lists of choices is an "and group".
            Must match any of the first AND any of each of the subsequent
            groups.

        {'field1': some filter}: Match each field with the filter given:
            A CompositeAndFilter. The filter class must have a key type of
            'composite'.

        {'nolink': True}: A special object which means to find objects not
            linked to the objects in this column. i.e. If this is a tags
            column, find untagged objects.
        """
        kwargs = {}
        filter_spec = json.loads(filter_json)
        filter_type = self.ds.filter_type()
        types = filter_type.filter_key_types()
        for key, data in filter_spec.iteritems():
            key_type = types.get(key, None)
            if key_type is None:
                # empty lists are the same as no filter
                if data == []:
                    continue

                elif (isinstance(data, list) and
                        len(data) > 0 and
                        isinstance(data[0], list)):
                    kwargs[key] = AndGroupFilter([
                        OrGroupFilter([
                            MatchFilter(v)
                            for v in or_f
                            ])
                        for or_f in data])

                elif isinstance(data, list) and len(data) > 0:
                    kwargs[key] = OrGroupFilter([
                        MatchFilter(v)
                        for v in data
                        ])

                elif isinstance(data, dict) and 'nolink' in data:
                    kwargs[key] = UnlinkedFilter()

                else:
                    kwargs[key] = MatchFilter(data)

            elif key_type == 'date_range':
                date_strings = filter_spec.get(key, None)
                dates = [
                    (datetime.strptime(d, "%m/%d/%Y") if d else None)
                    for d in date_strings]

                kwargs[key] = DateRangeFilter(dates)

            elif key_type == 'composite':
                value_map = {
                    col: MatchFilter(value)
                    for col, value in filter_spec.get(key, {}).iteritems()
                }

                kwargs[key] = CompositeAndFilter(value_map)

            else:
                message = 'DataSource %s has unknown filter key type %s' % (
                    self.ds.__class__.__name__,
                    repr(key_type))
                raise KeyError(message)

        return filter_type(**kwargs)
예제 #17
0
 def test_and_group_empty(self):
     """Empty And group should result in no comparisons."""
     qs = MockQuerySet()
     result = apply_filter_to_queryset(qs, AndGroupFilter([]), 'z')
     self.assert_filters_equals([], result.filters)