Allow ignored get vars.
[django-pagination.git] / fnp_django_pagination / tests / test_main.py
1 # Copyright (c) 2008, Eric Florenzano
2 # Copyright (c) 2010, 2011 Linaro Limited
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
9 #     * Redistributions of source code must retain the above copyright
10 #       notice, this list of conditions and the following disclaimer.
11 #     * Redistributions in binary form must reproduce the above
12 #       copyright notice, this list of conditions and the following
13 #       disclaimer in the documentation and/or other materials provided
14 #       with the distribution.
15 #     * Neither the name of the author nor the names of other
16 #       contributors may be used to endorse or promote products derived
17 #       from this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 from django.core.paginator import Paginator
32 from django.http import HttpRequest as DjangoHttpRequest
33 from django.template import Template, Context
34 from django.test import SimpleTestCase
35 from fnp_django_pagination.paginator import InfinitePaginator, FinitePaginator
36 from fnp_django_pagination.templatetags.pagination_tags import paginate
37 from fnp_django_pagination.middleware import PaginationMiddleware
38
39
40 class HttpRequest(DjangoHttpRequest):
41      page = lambda self, suffix: 1
42
43
44 class CommonTestCase(SimpleTestCase):
45     def test_records_for_the_first_page(self):
46         p = Paginator(range(15), 2)
47         pg = paginate({'paginator': p, 'page_obj': p.page(1)})
48         self.assertListEqual(pg['pages'], [1, 2, 3, 4, 5, 6, 7, 8])
49         self.assertEqual(pg['records']['first'], 1)
50         self.assertEqual(pg['records']['last'], 2)
51
52     def test_records_for_the_last_page(self):
53         p = Paginator(range(15), 2)
54         pg = paginate({'paginator': p, 'page_obj': p.page(8)})
55         self.assertListEqual(pg['pages'], [1, 2, 3, 4, 5, 6, 7, 8])
56         self.assertEqual(pg['records']['first'], 15)
57         self.assertEqual(pg['records']['last'], 15)
58
59     def test_pages_list(self):
60         p = Paginator(range(17), 2)
61         self.assertEqual(paginate({'paginator': p, 'page_obj': p.page(1)})['pages'], [1, 2, 3, 4, 5, 6, 7, 8, 9])
62
63     def test_page_with_empty_objects_list(self):
64         p = Paginator(range(0), 2)
65         self.assertListEqual(paginate({'paginator': p, 'page_obj': p.page(1)})['pages'], [1])
66
67
68 class DefaultWindowTestCase(SimpleTestCase):
69     """
70     Test paginate using default window setting
71     moving the window from 1 ... to end
72     window size = 2, margin = 2
73     window = 2 -> show 5 pages
74     """
75     def setUp(self):
76         self.p = Paginator(range(31), 2)
77
78     def test_on_start_page_1(self):
79         # [1] 2 3 4 5 ... 15, 16
80         self.assertListEqual(
81             paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 2, 2)['pages'],
82             [1, 2, 3, 4, 5, None, 15, 16]
83         )
84
85     def test_on_start_page_2(self):
86         # 1 [2] 3 4 5 ... 15, 16
87         self.assertListEqual(
88             paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 2, 2)['pages'],
89             [1, 2, 3, 4, 5, None, 15, 16]
90         )
91
92     def test_on_start_page_3(self):
93         # 1 2 [3] 4 5 ... 15, 16
94         self.assertListEqual(
95             paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 2)['pages'],
96             [1, 2, 3, 4, 5, None, 15, 16]
97         )
98
99     def test_on_start_page_4(self):
100         # 1 2 3 [4] 5 6 ... 15, 16
101         self.assertListEqual(
102             paginate({'paginator': self.p, 'page_obj': self.p.page(4)}, 2, 2)['pages'],
103             [1, 2, 3, 4, 5, 6, None, 15, 16])
104
105     def test_on_start_page_5(self):
106         # 1 2 3 4 [5] 6 7 ... 15, 16
107         self.assertListEqual(
108             paginate({'paginator': self.p, 'page_obj': self.p.page(5)}, 2, 2)['pages'],
109             [1, 2, 3, 4, 5, 6, 7, None, 15, 16]
110         )
111
112     def test_in_middle(self):
113         # 1 2 ... 5 6 [7] 8 9 ... 15, 16
114         self.assertListEqual(
115             paginate({'paginator': self.p, 'page_obj': self.p.page(7)}, 2, 2)['pages'],
116             [1, 2, None, 5, 6, 7, 8, 9, None, 15, 16]
117         )
118
119     def test_on_end_page_13(self):
120         # 1 2 ... 12 [13] 14 15 16
121         self.assertListEqual(
122             paginate({'paginator': self.p, 'page_obj': self.p.page(13)}, 2, 2)['pages'],
123             [1, 2, None, 11, 12, 13, 14, 15, 16],
124         )
125
126     def test_on_end(self):
127         # 1 2 ... 12 13 14 15 [16
128         self.assertListEqual(
129             paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 2, 2)['pages'],
130             [1, 2, None, 12, 13, 14, 15, 16]
131         )
132
133
134 class NoMarginTestCase(SimpleTestCase):
135     def setUp(self):
136         self.p = Paginator(range(31), 2)
137
138     def test_on_start(self):
139         self.assertListEqual(
140             paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 0)['pages'],
141             [1, 2, 3, 4, 5, None],
142         )
143
144     def test_in_middle(self):
145         self.assertListEqual(
146             paginate({'paginator': self.p, 'page_obj': self.p.page(5)}, 2, 0)['pages'],
147             [None, 3, 4, 5, 6, 7, None],
148         )
149
150     def test_on_end(self):
151         self.assertListEqual(
152             paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 2, 0)['pages'],
153             [None, 12, 13, 14, 15, 16],
154         )
155
156
157 class ZeroWindowZeroMarginTestCase(SimpleTestCase):
158     """
159     Test paginate using window=0 and margin=0
160     """
161     def setUp(self):
162         self.p = Paginator(range(31), 2)
163
164     def test_on_start_page_1(self):
165         self.assertListEqual(
166             paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 0, 0)['pages'],
167             [1, None],
168         )
169
170     def test_in_middle_page_2(self):
171         self.assertListEqual(
172             paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 0, 0)['pages'],
173             [None, 2, None],
174         )
175
176     def test_in_middle_page_3(self):
177         self.assertListEqual(
178             paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 0, 0)['pages'],
179             [None, 3, None],
180         )
181
182     def test_in_middle_page_10(self):
183         self.assertListEqual(
184             paginate({'paginator': self.p, 'page_obj': self.p.page(10)}, 0, 0)['pages'],
185             [None, 10, None],
186         )
187
188     def test_in_middle_page_14(self):
189         self.assertListEqual(
190             paginate({'paginator': self.p, 'page_obj': self.p.page(14)}, 0, 0)['pages'],
191             [None, 14, None],
192         )
193
194     def test_in_middle_page_15(self):
195         self.assertListEqual(
196             paginate({'paginator': self.p, 'page_obj': self.p.page(15)}, 0, 0)['pages'],
197             [None, 15, None],
198         )
199
200     def test_on_end_page_16(self):
201         self.assertListEqual(
202             paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 0, 0)['pages'],
203             [None, 16],
204         )
205
206
207 class NoEllipsisTestCase(SimpleTestCase):
208     """
209     Tests a case where should be no any ellipsis pages.
210     """
211     def setUp(self):
212         self.p = Paginator(range(100), 25)
213
214     def test_on_start(self):
215         self.assertListEqual(
216             paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 2, 0)['pages'],
217             [1, 2, 3, 4],
218         )
219
220     def test_in_middle_page_2(self):
221         self.assertListEqual(
222             paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 2, 0)['pages'],
223             [1, 2, 3, 4],
224         )
225
226     def test_in_middle_page_3(self):
227         self.assertListEqual(
228             paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 0)['pages'],
229             [1, 2, 3, 4],
230         )
231
232     def test_on_end(self):
233         self.assertListEqual(
234             paginate({'paginator': self.p, 'page_obj': self.p.page(4)}, 2, 0)['pages'],
235             [1, 2, 3, 4],
236         )
237
238
239 class SpecialTestCase(SimpleTestCase):
240     def test_middle_with_no_window_and_margin_1(self):
241         p = Paginator(range(31), 2)
242         self.assertListEqual(
243             paginate({'paginator': p, 'page_obj': p.page(5)}, 0, 1)['pages'],
244             [1, None, 5, None, 16],
245         )
246
247     def test_middle_with_no_window_and_margin_4(self):
248         p = Paginator(range(21), 2, 1)
249         self.assertListEqual(
250             paginate({'paginator': p, 'page_obj': p.page(1)}, 0, 4)['pages'],
251             [1, 2, 3, 4, None, 7, 8, 9, 10],
252         )
253
254
255 class TemplateRenderingTestCase(SimpleTestCase):
256     def test_default_tag_options(self):
257         t = Template("{% load pagination_tags %}{% autopaginate var %}{% paginate %}")
258         self.assertIn(
259             '<div class="pagination">',
260             t.render(Context({'var': range(21), 'request': HttpRequest()})),
261         )
262
263     def test_paginate_by_option(self):
264         t = Template("{% load pagination_tags %}{% autopaginate var 20 %}{% paginate %}")
265         self.assertIn(
266             '<div class="pagination">',
267             t.render(Context({'var': range(21), 'request': HttpRequest()})),
268         )
269
270     def test_orphans_option(self):
271         t = Template("{% load pagination_tags %}{% autopaginate var by %}{% paginate %}")
272         content = t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()}))
273         self.assertIn('<div class="pagination">', content)
274         self.assertIn('<a href="?page=2"', content)
275
276     def test_as_option(self):
277         t = Template("{% load pagination_tags %}{% autopaginate var by as foo %}{{ foo }}")
278         self.assertEqual(
279             t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()})),
280             str(range(20)),
281         )
282
283     def test_multiple_pagination(self):
284         t = Template("{% load pagination_tags %}{% autopaginate var2 by as foo2 %}{% paginate %}"
285                      "{% autopaginate var by as foo %}{% paginate %}")
286         content = t.render(Context({'var': range(21), 'var2': range(50, 121), 'by': 20, 'request': HttpRequest()}))
287         self.assertIn('<div class="pagination">', content)
288         self.assertIn('<a href="?page_var2=2"', content)
289         self.assertIn('<a href="?page_var=2"', content)
290
291
292 class InfinitePaginatorTestCase(SimpleTestCase):
293     def setUp(self):
294         self.p = InfinitePaginator(range(20), 2, link_template='/bacon/page/%d')
295
296     def test_paginator_repr(self):
297         self.assertEqual(
298             repr(InfinitePaginator),
299             "<class 'fnp_django_pagination.paginator.InfinitePaginator'>",
300         )
301
302     def test_validate_number(self):
303         self.assertEqual(self.p.validate_number(2), 2)
304
305     def test_orphans(self):
306         self.assertEqual(self.p.orphans, 0)
307
308     def test_page_repr(self):
309         self.assertEqual(repr(self.p.page(3)), '<Page 3>')
310
311     def test_page_end_index(self):
312         self.assertEqual(self.p.page(3).end_index(), 6)
313
314     def test_page_has_next(self):
315         self.assertTrue(self.p.page(3).has_next(), True)
316
317     def test_page_has_previous(self):
318         self.assertTrue(self.p.page(3).has_previous(), True)
319
320     def test_page_next_link(self):
321         self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
322
323     def test_page_previous_link(self):
324         self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
325
326     def test_last_page_which_has_no_next_page(self):
327         self.assertFalse(self.p.page(10).has_next())
328
329     def test_first_page_which_has_no_previous_page(self):
330         self.assertFalse(self.p.page(1).has_previous())
331
332
333 class FinitePaginatorTestCase(SimpleTestCase):
334     def setUp(self):
335         self.p = FinitePaginator(range(20), 2, offset=10, link_template='/bacon/page/%d')
336
337     def test_repr(self):
338         self.assertEqual(
339             repr(FinitePaginator),
340             "<class 'fnp_django_pagination.paginator.FinitePaginator'>"
341         )
342
343     def test_validate_number(self):
344         self.assertEqual(self.p.validate_number(2), 2)
345
346     def test_orphans(self):
347         self.assertEqual(self.p.orphans, 0)
348
349     def test_page_repr(self):
350         self.assertEqual(repr(self.p.page(3)), '<Page 3>')
351
352     def test_page_start_index(self):
353         self.assertEqual(self.p.page(3).start_index(), 10)
354
355     def test_page_end(self):
356         self.assertEqual(self.p.page(3).end_index(), 6)
357
358     def test_page_has_next(self):
359         self.assertTrue(self.p.page(3).has_next(), True)
360
361     def test_page_has_previous(self):
362         self.assertTrue(self.p.page(3).has_previous(), True)
363
364     def test_page_next_link(self):
365         self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
366
367     def test_page_previous_link(self):
368         self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
369
370     def test_on_start_page_repr(self):
371         self.assertEqual(repr(self.p.page(2)), '<Page 2>')
372
373     def test_on_start_has_no_next(self):
374         self.assertTrue(self.p.page(2).has_next(), False)
375
376     def test_on_start_has_previous(self):
377         self.assertTrue(self.p.page(2).has_previous(), True)
378
379     def test_on_start_has_next_link(self):
380         self.assertEqual(self.p.page(2).next_link(), '/bacon/page/3')
381
382     def test_on_start_has_previous_link(self):
383         self.assertEqual(self.p.page(2).previous_link(), '/bacon/page/1')
384
385
386 class MiddlewareTestCase(SimpleTestCase):
387     """
388     Test middleware
389     """
390     def test_get_page_in_request(self):
391         middleware = PaginationMiddleware(lambda: None)
392         request = DjangoHttpRequest()
393         middleware.process_request(request)
394         self.assertEqual(request.page(''), 1)