def test_composite_and_missing_in_db(self):
     """
     Pass through branches of a CompositeAndFilter not indexed by the data
     source.
     """
     self.maxDiff = 10000
     result = adorn_filter(
         None, self.ds,
         ContactsFilter(
             locations=CompositeAndFilter({
                 'city': MatchFilter('indy'),
                 'state': MatchFilter('IN'),
                 'county': MatchFilter('marion'),
             })))
     self.assertEqual([{
         'locations': {
             'city': ['indy'],
             'state': ['IN'],
             'county': ['marion'],
         },
     }], self.ds.adorn_calls)
     self.assertEqual(
         ContactsFilter(locations=CompositeAndFilter(
             {
                 'city': MatchFilter({
                     'value': 'indy',
                     'display': 'Indy'
                 }),
                 'state': MatchFilter({
                     'value': 'IN',
                     'display': 'Indiana'
                 }),
                 'county': MatchFilter('marion'),
             })), result)
 def test_composite_and(self):
     """Test adorning a CompositeAndFilter."""
     self.maxDiff = 10000
     result = adorn_filter(
         None, self.ds,
         ContactsFilter(
             locations=CompositeAndFilter({
                 'city': MatchFilter('indy'),
                 'state': MatchFilter('IN'),
             })))
     self.assertEqual([{
         'locations': {
             'city': ['indy'],
             'state': ['IN'],
         },
     }], self.ds.adorn_calls)
     self.assertEqual(
         ContactsFilter(locations=CompositeAndFilter(
             {
                 'city': MatchFilter({
                     'value': 'indy',
                     'display': 'Indy'
                 }),
                 'state': MatchFilter({
                     'value': 'IN',
                     'display': 'Indiana'
                 }),
             })), result)
 def test_city_filter(self):
     """Test that city filter is built properly."""
     result = self.driver.build_filter('{"locations": {"city": "Indy"}}')
     self.assertEquals(
         ContactsFilter(
             locations=CompositeAndFilter({'city': MatchFilter('Indy')})),
         result)
 def test_clone_without_full(self):
     """Cloning should remove certain fields."""
     filter = ContactsFilter(tags=['C'],
                             locations=CompositeAndFilter({
                                 'city':
                                 MatchFilter('A'),
                                 'state':
                                 MatchFilter('B')
                             }))
     expected_with_city = ContactsFilter(tags=['C'],
                                         locations=CompositeAndFilter(
                                             {'city': MatchFilter('A')}))
     expected_with_state = ContactsFilter(tags=['C'],
                                          locations=CompositeAndFilter(
                                              {'state': MatchFilter('B')}))
     self.assertEqual(expected_with_state, filter.clone_without_city())
     self.assertEqual(expected_with_city, filter.clone_without_state())
Example #5
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())
 def test_clone_without_partners(self):
     locations_filter = CompositeAndFilter({
         'city': MatchFilter('A'),
         'state': MatchFilter('B')
     })
     filter = ContactsFilter(partner=[1, 2, 3], locations=locations_filter)
     expected_without_partners = ContactsFilter(locations=locations_filter)
     self.assertEqual(expected_without_partners,
                      filter.clone_without_partner())
 def test_help_city(self):
     """Check city help works and ignores current city filter."""
     ds = ContactsDataSource()
     recs = ds.help_city(
         self.company,
         ContactsFilter(locations=CompositeAndFilter(
             {'city': MatchFilter('Los Angeles')})), "angel")
     actual = {r['value'] for r in recs}
     self.assertEqual({'Los Angeles'}, actual)
 def test_help_state(self):
     """Check state help works and ignores current state filter."""
     ds = ContactsDataSource()
     recs = ds.help_state(
         self.company,
         ContactsFilter(
             locations=CompositeAndFilter({'state': MatchFilter('zz')})),
         "i")
     actual = {r['value'] for r in recs}
     self.assertEqual({'IL', 'IN'}, actual)
Example #9
0
 def test_filter_by_city(self):
     """Should show only commrecs with correct city."""
     ds = CommRecordsDataSource()
     recs = ds.run_unaggregated(
         self.company,
         CommRecordsFilter(locations=CompositeAndFilter(
             {'city': MatchFilter('Los Angeles')})), [])
     subjects = {r['subject'] for r in recs}
     expected = {self.record_3.subject}
     self.assertEqual(expected, subjects)
 def test_filter_by_city(self):
     """Should show only contacts with correct city."""
     ds = ContactsDataSource()
     recs = ds.run_unaggregated(
         self.company,
         ContactsFilter(locations=CompositeAndFilter(
             {'city': MatchFilter('Los Angeles')})), [])
     names = [r['name'] for r in recs]
     expected = [self.sue.name]
     self.assertEqual(expected, names)
 def test_composite_and_group_missing_db_field(self):
     """
     Failing to pass a db field to a compsite and field should result in
     no comparison for that field.
     """
     qs = MockQuerySet()
     filt = CompositeAndFilter({'a': MatchFilter('b'), 'c': NoFilter()})
     result = apply_filter_to_queryset(qs, filt, {'a': 'aaa', 'b': 'bbb'})
     self.assert_filters_equals([Q(aaa='b')], result.filters)
     result = apply_filter_to_queryset(qs, filt, {'b', 'bbb'})
     self.assert_filters_equals([], result.filters)
Example #12
0
 def test_filter_by_state(self):
     """Should show only partners with correct state."""
     ds = PartnersDataSource()
     recs = ds.run_unaggregated(
         self.company,
         PartnersFilter(
             locations=CompositeAndFilter({
                 'state': MatchFilter('CA'),
             })), [])
     names = [r['name'] for r in recs]
     expected = [self.partner_b.name]
     self.assertEqual(expected, names)
Example #13
0
    def clone_without_city(self):
        """City help needs it's filter cleared before searching for help.

        Return a new CommRecordsFilter without the current city filter applied.
        """
        new_root = dict(self.__dict__)
        locations = new_root.get('locations', NoFilter())
        if locations:
            new_locations = dict(locations.field_map)
            if 'city' in locations.field_map:
                del new_locations['city']
            new_root['locations'] = CompositeAndFilter(new_locations)
        return CommRecordsFilter(**new_root)
Example #14
0
    def clone_without_state(self):
        """State help needs it's filter cleared before searching for help.

        Return a new PartnersFilter without the current state filter applied.
        """
        new_root = dict(self.__dict__)
        locations = new_root.get('locations', NoFilter())
        if locations:
            new_locations = dict(locations.field_map)
            if 'state' in locations.field_map:
                del new_locations['state']
            new_root['locations'] = CompositeAndFilter(new_locations)
        return PartnersFilter(**new_root)
 def test_passthrough_missing_composite_and(self):
     """
     Pass through  when all branches of a CompositeAndFilter are not indexed
     by the data source.
     """
     result = adorn_filter(
         None, self.ds,
         ContactsFilter(partner=CompositeAndFilter({
             'a': MatchFilter(1),
             'b': MatchFilter(2)
         })))
     self.assertEqual([{
         'partner': {
             'a': [1],
             'b': [2]
         },
     }], self.ds.adorn_calls)
     self.assertEqual(
         ContactsFilter(partner=CompositeAndFilter({
             'a': MatchFilter(1),
             'b': MatchFilter(2)
         })), result)
 def test_plain_filter_composite_and(self):
     """Convert CompositeAndFilter to plain object."""
     filt = ContactsFilter(
         locations=CompositeAndFilter({
             'city': MatchFilter('indy'),
             'state': MatchFilter('IN'),
         }))
     self.assertEqual({
         'locations': {
             'city': 'indy',
             'state': 'IN',
         },
     }, plain_filter(filt))
 def test_composite_and_group(self):
     """CompositeAndFilter should result in and'ed Q."""
     qs = MockQuerySet()
     filt = CompositeAndFilter({
         'a':
         MatchFilter('b'),
         'c':
         OrGroupFilter([MatchFilter('d'),
                        MatchFilter('e')])
     })
     result = apply_filter_to_queryset(qs, filt, {'a': 'aaa', 'c': 'ccc'})
     self.assert_filters_equals([
         Q(aaa='b') & (Q(ccc='d') | Q(ccc='e')),
     ], result.filters)
 def test_composite_and_partial_filter(self):
     """
     Only one branch of a CompositeAndFilter is specified.
     """
     self.maxDiff = 10000
     result = adorn_filter(
         None, self.ds,
         ContactsFilter(
             locations=CompositeAndFilter({
                 'city': MatchFilter('indy'),
             })))
     self.assertEqual([{
         'locations': {
             'city': ['indy'],
         },
     }], self.ds.adorn_calls)
     self.assertEqual(
         ContactsFilter(locations=CompositeAndFilter({
             'city':
             MatchFilter({
                 'value': 'indy',
                 'display': 'Indy'
             }),
         })), result)
Example #19
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)
 def test_composite_and_group_none(self):
     """Falsey branches of CompositeAndFilter should not compare."""
     qs = MockQuerySet()
     filt = CompositeAndFilter({'a': MatchFilter('b'), 'c': NoFilter()})
     result = apply_filter_to_queryset(qs, filt, {'a': 'aaa', 'c': 'ccc'})
     self.assert_filters_equals([Q(aaa='b')], result.filters)
 def test_composite_and_group_empty(self):
     """Empty CompositeAndFilter should result in no comparisons."""
     qs = MockQuerySet()
     filt = CompositeAndFilter({})
     result = apply_filter_to_queryset(qs, filt, {})
     self.assert_filters_equals([], result.filters)