def test_datetime_filter_day_range_selected(self): params = MultiValueDict({'date_published': ['1847-10-10..1847-10-23']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) start = date(1847, 10, 10) end = date(1847, 10, 24) self.assertEqual( list(qs_filtered), list(qs.filter(date_published__gte=start, date_published__lt=end))) # We only need 1 query if we've already told it what days to look at, # and there is data for more than one day. with self.assertNumQueries(1): choices = f.get_choices(qs_filtered) self.assertEqual( len([c for c in choices if c.link_type == FILTER_REMOVE]), 1) # There are at least 2 books in this range, on different days. add_choices = [c for c in choices if c.link_type == FILTER_ADD] self.assertTrue(len(add_choices) >= 2) self.assertTrue("16" in [c.label for c in add_choices])
def test_datetime_filter_max_depth(self): qs = Book.objects.all() params = MultiValueDict({'date_published': ['1813']}) f = DateTimeFilter('date_published', Book, params, max_depth='year') choices = f.get_choices(f.apply_filter(qs)) self.assertEqual(len(choices), 1) self.assertEqual(choices[0].link_type, FILTER_REMOVE)
def test_datetime_filter_day_range_selected(self): params = MultiValueDict({'date_published': ['1847-10-10..1847-10-23']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) start = date(1847, 10, 10) end = date(1847, 10, 24) self.assertEqual(list(qs_filtered), list(qs.filter(date_published__gte=start, date_published__lt=end))) # We only need 1 query if we've already told it what days to look at, # and there is data for more than one day. with self.assertNumQueries(1): choices = f.get_choices(qs_filtered) self.assertEqual(len([c for c in choices if c.link_type == FILTER_REMOVE]), 1) # There are at least 2 books in this range, on different days. add_choices = [c for c in choices if c.link_type == FILTER_ADD] self.assertTrue(len(add_choices) >= 2) self.assertTrue("16" in [c.label for c in add_choices])
def test_datetime_filter_drill_down_to_choice(self): """ Tests that if there is a choice that can be displayed, it will drill down to reach it. """ # Two birthdays in Jan 2011 Person.objects.create(name="Joe", date_of_birth=date(2011, 1, 10)) Person.objects.create(name="Peter", date_of_birth=date(2011, 1, 20)) # Chosen year = 2011 params = MultiValueDict({'date_of_birth': ['2011']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) # Expect 2011 as remove link self.assertEqual( ['2011'], [c.label for c in choices if c.link_type == FILTER_REMOVE]) # Expect January as display self.assertEqual( ['January'], [c.label for c in choices if c.link_type == FILTER_DISPLAY]) # Expect '10' and '20' as choices self.assertEqual( ['10', '20'], [c.label for c in choices if c.link_type == FILTER_ADD])
def test_datetime_filter_bridge_from_multi_to_single(self): """ Tests that bridge_choices will bridge from range (multi) choices to single choices. """ # Two birthdays in Jan 2011 Person.objects.create(name="Joe", date_of_birth=date(2011, 1, 10)) Person.objects.create(name="Peter", date_of_birth=date(2011, 1, 20)) # Chosen year = 2010 - 2011 params = MultiValueDict({'date_of_birth': ['2010..2011']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) # Expect 2010 - 2011 as remove link self.assertEqual( ['2010-2011'], [c.label for c in choices if c.link_type == FILTER_REMOVE]) # Expect 2011 and January as display self.assertEqual( ['2011', 'January'], [c.label for c in choices if c.link_type == FILTER_DISPLAY]) # Expect '10' and '20' as choices self.assertEqual( ['10', '20'], [c.label for c in choices if c.link_type == FILTER_ADD])
def test_datetime_filter_month_range_selected(self): params = MultiValueDict({'date_published': ['1818-08..1818-09']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) start = date(1818, 8, 1) end = date(1818, 10, 1) self.assertEqual( list(qs_filtered), list(qs.filter(date_published__gte=start, date_published__lt=end))) # We only need 1 query if we've already told it what months to look at, # and there is data for both months. with self.assertNumQueries(1): choices = f.get_choices(qs_filtered) self.assertEqual( len([c for c in choices if c.link_type == FILTER_REMOVE]), 1) # There are at least 2 books in this range, in different months self.assertEqual( len([c for c in choices if c.link_type == FILTER_ADD]), 2) self.assertEqual( [c.label for c in choices if c.link_type == FILTER_ADD], ['August', 'September'])
def test_datetime_filter_empty_qs(self): """ Tests that DateTimeFilter works when it is passed in an empty QuerySet. """ f = DateTimeFilter('date_published', Book, MultiValueDict(), max_links=10) qs = Book.objects.filter(id=1000) qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) self.assertEqual(len(choices), 0) self.assertEqual(len(qs_filtered), 0)
def test_datetime_filter_multiple_year_choices(self): """ Tests that DateTimeFilter can produce choices spanning a set of years (and limit to max_links) """ # This does drill down, and has multiple values. f = DateTimeFilter('date_published', Book, MultiValueDict(), max_links=10) qs = Book.objects.all() # We have enough data that it will not show a simple list of years. choices = f.get_choices(qs) self.assertTrue(len(choices) <= 10) self.assertTrue('-' in choices[0].label)
def test_datetime_filter_select_year_display_month(self): # Tests that if a year is selected, and only one thing matches, # the month should be displayed in 'display' mode. qs = Book.objects.filter(id=1) params = MultiValueDict(dict(date_published=[str(qs[0].date_published.year)])) f = DateTimeFilter('date_published', Book, params, max_links=10, max_depth='month') choices = f.get_choices(qs) self.assertEqual(len(choices), 2) self.assertEqual(choices[0].link_type, FILTER_REMOVE) self.assertEqual(choices[0].label, str(qs[0].date_published.year)) self.assertEqual(choices[1].link_type, FILTER_DISPLAY)
def test_datetime_filter_day_ranges_end(self): """ Test that the ranges for day selection end at the right point (e.g. 31) """ # September for i in range(1, 30): Person.objects.create(name="Joe", date_of_birth=date(2011, 9, i)) params = MultiValueDict({'date_of_birth': ['2011-09']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) self.assertEqual(choices[-1].label[-3:], "-30") # October for i in range(2, 31): Person.objects.create(name="Joe", date_of_birth=date(2011, 10, i)) params = MultiValueDict({'date_of_birth': ['2011-10']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) self.assertEqual(choices[-1].label[-3:], "-31")
def test_datetime_filter_start_at_year(self): # Tests that the first filter shown is a year, not a day, # even if initial query gets you down to a day. params = MultiValueDict() qs = Book.objects.filter(id=1) f = DateTimeFilter('date_published', Book, params, max_links=10) choices = f.get_choices(qs) self.assertEqual(len(choices), 3) self.assertEqual(choices[0].link_type, FILTER_DISPLAY) self.assertEqual(choices[0].label, str(qs[0].date_published.year)) self.assertEqual(choices[1].link_type, FILTER_DISPLAY) self.assertEqual(choices[2].link_type, FILTER_DISPLAY) self.assertEqual(choices[2].label, str(qs[0].date_published.day))
def test_datetime_filter_single_year_selected(self): params = MultiValueDict({'date_published': ['1818']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) self.assertEqual(list(qs_filtered), list(qs.filter(date_published__year=1818))) # We only need 1 query if we've already told it what year to look at. with self.assertNumQueries(1): choices = f.get_choices(qs_filtered) # There are at least 2 books in 1818, in different months. self.assertTrue(len([c for c in choices if c.link_type == FILTER_ADD]) >= 2) self.assertEqual(len([c for c in choices if c.link_type == FILTER_REMOVE]), 1)
def test_datetime_filter_single_year_selected(self): params = MultiValueDict({'date_published': ['1818']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) self.assertEqual(list(qs_filtered), list(qs.filter(date_published__year=1818))) # We only need 1 query if we've already told it what year to look at. with self.assertNumQueries(1): choices = f.get_choices(qs_filtered) # There are at least 2 books in 1818, in different months. self.assertTrue( len([c for c in choices if c.link_type == FILTER_ADD]) >= 2) self.assertEqual( len([c for c in choices if c.link_type == FILTER_REMOVE]), 1)
def test_datetime_filter_select_year_display_month(self): # Tests that if a year is selected, and only one thing matches, # the month should be displayed in 'display' mode. qs = Book.objects.filter(id=1) params = MultiValueDict( dict(date_published=[str(qs[0].date_published.year)])) f = DateTimeFilter('date_published', Book, params, max_links=10, max_depth='month') choices = f.get_choices(qs) self.assertEqual(len(choices), 2) self.assertEqual(choices[0].link_type, FILTER_REMOVE) self.assertEqual(choices[0].label, str(qs[0].date_published.year)) self.assertEqual(choices[1].link_type, FILTER_DISPLAY)
def test_datetime_filter_single_day_selected(self): params = MultiValueDict({'date_published': ['1847-10-16']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) self.assertEqual(list(qs_filtered), list(qs.filter(date_published__year=1847, date_published__month=10, date_published__day=16))) # We need 0 queries if we've already told it what day to look at. with self.assertNumQueries(0): choices = f.get_choices(qs_filtered) # There can be no add links. self.assertEqual(len([c for c in choices if c.link_type == FILTER_ADD]), 0) self.assertEqual(len([c for c in choices if c.link_type == FILTER_REMOVE]), 1)
def test_datetime_filter_remove_choices_complete(self): """ Tests that in the case produced in test_datetime_filter_drill_down_to_choice, the remove links display correctly. """ # Two birthdays in Jan 2011 Person.objects.create(name="Joe", date_of_birth=date(2011, 1, 10)) Person.objects.create(name="Peter", date_of_birth=date(2011, 1, 20)) # Chosen year = 2011, and date = 2011-01-10 params = MultiValueDict({'date_of_birth': ['2011', '2011-01-10']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) self.assertEqual([('2011', FILTER_REMOVE), ('January', FILTER_DISPLAY), ('10', FILTER_REMOVE), ], [(c.label, c.link_type) for c in choices])
def test_datetime_filter_remove_choices_complete(self): """ Tests that in the case produced in test_datetime_filter_drill_down_to_choice, the remove links display correctly. """ # Two birthdays in Jan 2011 Person.objects.create(name="Joe", date_of_birth=date(2011, 1, 10)) Person.objects.create(name="Peter", date_of_birth=date(2011, 1, 20)) # Chosen year = 2011, and date = 2011-01-10 params = MultiValueDict({'date_of_birth': ['2011', '2011-01-10']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) self.assertEqual([ ('2011', FILTER_REMOVE), ('January', FILTER_DISPLAY), ('10', FILTER_REMOVE), ], [(c.label, c.link_type) for c in choices])
def test_datetime_filter_drill_down_to_choice(self): """ Tests that if there is a choice that can be displayed, it will drill down to reach it. """ # Two birthdays in Jan 2011 Person.objects.create(name="Joe", date_of_birth=date(2011, 1, 10)) Person.objects.create(name="Peter", date_of_birth=date(2011, 1, 20)) # Chosen year = 2011 params = MultiValueDict({'date_of_birth': ['2011']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) # Expect 2011 as remove link self.assertEqual(['2011'], [c.label for c in choices if c.link_type == FILTER_REMOVE]) # Expect January as display self.assertEqual(['January'], [c.label for c in choices if c.link_type == FILTER_DISPLAY]) # Expect '10' and '20' as choices self.assertEqual(['10', '20'], [c.label for c in choices if c.link_type == FILTER_ADD])
def test_datetime_filter_bridge_from_multi_to_single(self): """ Tests that bridge_choices will bridge from range (multi) choices to single choices. """ # Two birthdays in Jan 2011 Person.objects.create(name="Joe", date_of_birth=date(2011, 1, 10)) Person.objects.create(name="Peter", date_of_birth=date(2011, 1, 20)) # Chosen year = 2010 - 2011 params = MultiValueDict({'date_of_birth': ['2010..2011']}) f = DateTimeFilter('date_of_birth', Person, params) qs = Person.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) # Expect 2010 - 2011 as remove link self.assertEqual(['2010-2011'], [c.label for c in choices if c.link_type == FILTER_REMOVE]) # Expect 2011 and January as display self.assertEqual(['2011', 'January'], [c.label for c in choices if c.link_type == FILTER_DISPLAY]) # Expect '10' and '20' as choices self.assertEqual(['10', '20'], [c.label for c in choices if c.link_type == FILTER_ADD])
def test_datetime_filter_month_range_selected(self): params = MultiValueDict({'date_published': ['1818-08..1818-09']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) start = date(1818, 8, 1) end = date(1818, 10, 1) self.assertEqual(list(qs_filtered), list(qs.filter(date_published__gte=start, date_published__lt=end))) # We only need 1 query if we've already told it what months to look at, # and there is data for both months. with self.assertNumQueries(1): choices = f.get_choices(qs_filtered) self.assertEqual(len([c for c in choices if c.link_type == FILTER_REMOVE]), 1) # There are at least 2 books in this range, in different months self.assertEqual(len([c for c in choices if c.link_type == FILTER_ADD]), 2) self.assertEqual([c.label for c in choices if c.link_type == FILTER_ADD], ['August', 'September'])
def test_datetime_filter_single_day_selected(self): params = MultiValueDict({'date_published': ['1847-10-16']}) f = DateTimeFilter('date_published', Book, params, max_links=10) qs = Book.objects.all() # Should get a number of books in queryset. qs_filtered = f.apply_filter(qs) self.assertEqual( list(qs_filtered), list( qs.filter(date_published__year=1847, date_published__month=10, date_published__day=16))) # We need 0 queries if we've already told it what day to look at. with self.assertNumQueries(0): choices = f.get_choices(qs_filtered) # There can be no add links. self.assertEqual( len([c for c in choices if c.link_type == FILTER_ADD]), 0) self.assertEqual( len([c for c in choices if c.link_type == FILTER_REMOVE]), 1)
def test_datetime_filter_remove_broad(self): """ If we remove a broader choice (e.g. year), the more specific choices (e.g. day) should be removed too. """ # This should hold whichever order the params are defined: params1 = MultiValueDict({ 'date_published': [ '1818-08-24', '1818-08-24..1818-08-30', '1818-08', '1818-08..1818-10', '1818..1819', '1818' ] }) params2 = MultiValueDict({ 'date_published': [ '1818..1819', '1818', '1818-08..1818-10', '1818-08', '1818-08-24..1818-08-30', '1818-08-24', ] }) for p in [params1, params2]: f = DateTimeFilter('date_published', Book, p) qs = Book.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) # First choice should be for '1818-1819' and remove all 'date_published' self.assertEqual(choices[0].label, '1818-1819') self.assertEqual(choices[0].link_type, FILTER_REMOVE) self.assertEqual(choices[0].params.getlist('date_published'), []) self.assertEqual(choices[1].link_type, FILTER_REMOVE) self.assertEqual(choices[1].params.getlist('date_published'), ['1818..1819']) self.assertEqual(choices[2].link_type, FILTER_REMOVE) self.assertEqual(choices[2].params.getlist('date_published'), [ '1818..1819', '1818', ]) self.assertEqual(choices[3].link_type, FILTER_REMOVE) self.assertEqual(choices[3].params.getlist('date_published'), [ '1818..1819', '1818', '1818-08..1818-10', ]) self.assertEqual(choices[4].link_type, FILTER_REMOVE) self.assertEqual(choices[4].params.getlist('date_published'), [ '1818..1819', '1818', '1818-08..1818-10', '1818-08', ]) self.assertEqual(choices[5].link_type, FILTER_REMOVE) self.assertEqual(choices[5].params.getlist('date_published'), [ '1818..1819', '1818', '1818-08..1818-10', '1818-08', '1818-08-24..1818-08-30', ])
def test_datetime_filter_invalid_query(self): self.do_invalid_query_param_test( lambda params: DateTimeFilter( 'date_published', Book, params, max_links=10), MultiValueDict({'date_published': ['1818xx']}))
def test_datetime_filter_remove_broad(self): """ If we remove a broader choice (e.g. year), the more specific choices (e.g. day) should be removed too. """ # This should hold whichever order the params are defined: params1 = MultiValueDict({'date_published': ['1818-08-24', '1818-08-24..1818-08-30', '1818-08', '1818-08..1818-10', '1818..1819', '1818']}) params2 = MultiValueDict({'date_published': ['1818..1819', '1818', '1818-08..1818-10', '1818-08', '1818-08-24..1818-08-30', '1818-08-24', ]}) for p in [params1, params2]: f = DateTimeFilter('date_published', Book, p) qs = Book.objects.all() qs_filtered = f.apply_filter(qs) choices = f.get_choices(qs_filtered) # First choice should be for '1818-1819' and remove all 'date_published' self.assertEqual(choices[0].label, '1818-1819') self.assertEqual(choices[0].link_type, FILTER_REMOVE) self.assertEqual(choices[0].params.getlist('date_published'), []) self.assertEqual(choices[1].link_type, FILTER_REMOVE) self.assertEqual(choices[1].params.getlist('date_published'), ['1818..1819']) self.assertEqual(choices[2].link_type, FILTER_REMOVE) self.assertEqual(choices[2].params.getlist('date_published'), ['1818..1819', '1818', ]) self.assertEqual(choices[3].link_type, FILTER_REMOVE) self.assertEqual(choices[3].params.getlist('date_published'), ['1818..1819', '1818', '1818-08..1818-10', ]) self.assertEqual(choices[4].link_type, FILTER_REMOVE) self.assertEqual(choices[4].params.getlist('date_published'), ['1818..1819', '1818', '1818-08..1818-10', '1818-08', ]) self.assertEqual(choices[5].link_type, FILTER_REMOVE) self.assertEqual(choices[5].params.getlist('date_published'), ['1818..1819', '1818', '1818-08..1818-10', '1818-08', '1818-08-24..1818-08-30', ])