1 # Copyright (c) 2008, Eric Florenzano
2 # Copyright (c) 2010, 2011 Linaro Limited
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
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.
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.
31 from django.core.paginator import Paginator
32 from django.http import HttpRequest as DjangoHttpRequest
33 from django.template import Template, Context
36 from django.test import SimpleTestCase
37 except ImportError: # Django 1.2 compatible
38 from django.test import TestCase as SimpleTestCase
40 from fnp_django_pagination.paginator import InfinitePaginator, FinitePaginator
41 from fnp_django_pagination.templatetags.pagination_tags import paginate
42 from fnp_django_pagination.middleware import PaginationMiddleware
45 class HttpRequest(DjangoHttpRequest):
46 page = lambda self, suffix: 1
49 class CommonTestCase(SimpleTestCase):
50 def test_records_for_the_first_page(self):
51 p = Paginator(range(15), 2)
52 pg = paginate({'paginator': p, 'page_obj': p.page(1)})
53 self.assertListEqual(pg['pages'], [1, 2, 3, 4, 5, 6, 7, 8])
54 self.assertEqual(pg['records']['first'], 1)
55 self.assertEqual(pg['records']['last'], 2)
57 def test_records_for_the_last_page(self):
58 p = Paginator(range(15), 2)
59 pg = paginate({'paginator': p, 'page_obj': p.page(8)})
60 self.assertListEqual(pg['pages'], [1, 2, 3, 4, 5, 6, 7, 8])
61 self.assertEqual(pg['records']['first'], 15)
62 self.assertEqual(pg['records']['last'], 15)
64 def test_pages_list(self):
65 p = Paginator(range(17), 2)
66 self.assertEqual(paginate({'paginator': p, 'page_obj': p.page(1)})['pages'], [1, 2, 3, 4, 5, 6, 7, 8, 9])
68 def test_page_with_empty_objects_list(self):
69 p = Paginator(range(0), 2)
70 self.assertListEqual(paginate({'paginator': p, 'page_obj': p.page(1)})['pages'], [1])
73 class DefaultWindowTestCase(SimpleTestCase):
75 Test paginate using default window setting
76 moving the window from 1 ... to end
77 window size = 2, margin = 2
78 window = 2 -> show 5 pages
81 self.p = Paginator(range(31), 2)
83 def test_on_start_page_1(self):
84 # [1] 2 3 4 5 ... 15, 16
86 paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 2, 2)['pages'],
87 [1, 2, 3, 4, 5, None, 15, 16]
90 def test_on_start_page_2(self):
91 # 1 [2] 3 4 5 ... 15, 16
93 paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 2, 2)['pages'],
94 [1, 2, 3, 4, 5, None, 15, 16]
97 def test_on_start_page_3(self):
98 # 1 2 [3] 4 5 ... 15, 16
100 paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 2)['pages'],
101 [1, 2, 3, 4, 5, None, 15, 16]
104 def test_on_start_page_4(self):
105 # 1 2 3 [4] 5 6 ... 15, 16
106 self.assertListEqual(
107 paginate({'paginator': self.p, 'page_obj': self.p.page(4)}, 2, 2)['pages'],
108 [1, 2, 3, 4, 5, 6, None, 15, 16])
110 def test_on_start_page_5(self):
111 # 1 2 3 4 [5] 6 7 ... 15, 16
112 self.assertListEqual(
113 paginate({'paginator': self.p, 'page_obj': self.p.page(5)}, 2, 2)['pages'],
114 [1, 2, 3, 4, 5, 6, 7, None, 15, 16]
117 def test_in_middle(self):
118 # 1 2 ... 5 6 [7] 8 9 ... 15, 16
119 self.assertListEqual(
120 paginate({'paginator': self.p, 'page_obj': self.p.page(7)}, 2, 2)['pages'],
121 [1, 2, None, 5, 6, 7, 8, 9, None, 15, 16]
124 def test_on_end_page_13(self):
125 # 1 2 ... 12 [13] 14 15 16
126 self.assertListEqual(
127 paginate({'paginator': self.p, 'page_obj': self.p.page(13)}, 2, 2)['pages'],
128 [1, 2, None, 11, 12, 13, 14, 15, 16],
131 def test_on_end(self):
132 # 1 2 ... 12 13 14 15 [16
133 self.assertListEqual(
134 paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 2, 2)['pages'],
135 [1, 2, None, 12, 13, 14, 15, 16]
139 class NoMarginTestCase(SimpleTestCase):
141 self.p = Paginator(range(31), 2)
143 def test_on_start(self):
144 self.assertListEqual(
145 paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 0)['pages'],
146 [1, 2, 3, 4, 5, None],
149 def test_in_middle(self):
150 self.assertListEqual(
151 paginate({'paginator': self.p, 'page_obj': self.p.page(5)}, 2, 0)['pages'],
152 [None, 3, 4, 5, 6, 7, None],
155 def test_on_end(self):
156 self.assertListEqual(
157 paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 2, 0)['pages'],
158 [None, 12, 13, 14, 15, 16],
162 class ZeroWindowZeroMarginTestCase(SimpleTestCase):
164 Test paginate using window=0 and margin=0
167 self.p = Paginator(range(31), 2)
169 def test_on_start_page_1(self):
170 self.assertListEqual(
171 paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 0, 0)['pages'],
175 def test_in_middle_page_2(self):
176 self.assertListEqual(
177 paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 0, 0)['pages'],
181 def test_in_middle_page_3(self):
182 self.assertListEqual(
183 paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 0, 0)['pages'],
187 def test_in_middle_page_10(self):
188 self.assertListEqual(
189 paginate({'paginator': self.p, 'page_obj': self.p.page(10)}, 0, 0)['pages'],
193 def test_in_middle_page_14(self):
194 self.assertListEqual(
195 paginate({'paginator': self.p, 'page_obj': self.p.page(14)}, 0, 0)['pages'],
199 def test_in_middle_page_15(self):
200 self.assertListEqual(
201 paginate({'paginator': self.p, 'page_obj': self.p.page(15)}, 0, 0)['pages'],
205 def test_on_end_page_16(self):
206 self.assertListEqual(
207 paginate({'paginator': self.p, 'page_obj': self.p.page(16)}, 0, 0)['pages'],
212 class NoEllipsisTestCase(SimpleTestCase):
214 Tests a case where should be no any ellipsis pages.
217 self.p = Paginator(range(100), 25)
219 def test_on_start(self):
220 self.assertListEqual(
221 paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 2, 0)['pages'],
225 def test_in_middle_page_2(self):
226 self.assertListEqual(
227 paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 2, 0)['pages'],
231 def test_in_middle_page_3(self):
232 self.assertListEqual(
233 paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 0)['pages'],
237 def test_on_end(self):
238 self.assertListEqual(
239 paginate({'paginator': self.p, 'page_obj': self.p.page(4)}, 2, 0)['pages'],
244 class SpecialTestCase(SimpleTestCase):
245 def test_middle_with_no_window_and_margin_1(self):
246 p = Paginator(range(31), 2)
247 self.assertListEqual(
248 paginate({'paginator': p, 'page_obj': p.page(5)}, 0, 1)['pages'],
249 [1, None, 5, None, 16],
252 def test_middle_with_no_window_and_margin_4(self):
253 p = Paginator(range(21), 2, 1)
254 self.assertListEqual(
255 paginate({'paginator': p, 'page_obj': p.page(1)}, 0, 4)['pages'],
256 [1, 2, 3, 4, None, 7, 8, 9, 10],
260 class TemplateRenderingTestCase(SimpleTestCase):
261 def test_default_tag_options(self):
262 t = Template("{% load pagination_tags %}{% autopaginate var %}{% paginate %}")
264 '<div class="pagination">',
265 t.render(Context({'var': range(21), 'request': HttpRequest()})),
268 def test_paginate_by_option(self):
269 t = Template("{% load pagination_tags %}{% autopaginate var 20 %}{% paginate %}")
271 '<div class="pagination">',
272 t.render(Context({'var': range(21), 'request': HttpRequest()})),
275 def test_orphans_option(self):
276 t = Template("{% load pagination_tags %}{% autopaginate var by %}{% paginate %}")
277 content = t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()}))
278 self.assertIn('<div class="pagination">', content)
279 self.assertIn('<a href="?page=2"', content)
281 def test_as_option(self):
282 t = Template("{% load pagination_tags %}{% autopaginate var by as foo %}{{ foo }}")
284 t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()})),
288 def test_multiple_pagination(self):
289 t = Template("{% load pagination_tags %}{% autopaginate var2 by as foo2 %}{% paginate %}"
290 "{% autopaginate var by as foo %}{% paginate %}")
291 content = t.render(Context({'var': range(21), 'var2': range(50, 121), 'by': 20, 'request': HttpRequest()}))
292 self.assertIn('<div class="pagination">', content)
293 self.assertIn('<a href="?page_var2=2"', content)
294 self.assertIn('<a href="?page_var=2"', content)
297 class InfinitePaginatorTestCase(SimpleTestCase):
299 self.p = InfinitePaginator(range(20), 2, link_template='/bacon/page/%d')
301 def test_paginator_repr(self):
303 repr(InfinitePaginator),
304 "<class 'fnp_django_pagination.paginator.InfinitePaginator'>",
307 def test_validate_number(self):
308 self.assertEqual(self.p.validate_number(2), 2)
310 def test_orphans(self):
311 self.assertEqual(self.p.orphans, 0)
313 def test_page_repr(self):
314 self.assertEqual(repr(self.p.page(3)), '<Page 3>')
316 def test_page_end_index(self):
317 self.assertEqual(self.p.page(3).end_index(), 6)
319 def test_page_has_next(self):
320 self.assertTrue(self.p.page(3).has_next(), True)
322 def test_page_has_previous(self):
323 self.assertTrue(self.p.page(3).has_previous(), True)
325 def test_page_next_link(self):
326 self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
328 def test_page_previous_link(self):
329 self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
331 def test_last_page_which_has_no_next_page(self):
332 self.assertFalse(self.p.page(10).has_next())
334 def test_first_page_which_has_no_previous_page(self):
335 self.assertFalse(self.p.page(1).has_previous())
338 class FinitePaginatorTestCase(SimpleTestCase):
340 self.p = FinitePaginator(range(20), 2, offset=10, link_template='/bacon/page/%d')
344 repr(FinitePaginator),
345 "<class 'fnp_django_pagination.paginator.FinitePaginator'>"
348 def test_validate_number(self):
349 self.assertEqual(self.p.validate_number(2), 2)
351 def test_orphans(self):
352 self.assertEqual(self.p.orphans, 0)
354 def test_page_repr(self):
355 self.assertEqual(repr(self.p.page(3)), '<Page 3>')
357 def test_page_start_index(self):
358 self.assertEqual(self.p.page(3).start_index(), 10)
360 def test_page_end(self):
361 self.assertEqual(self.p.page(3).end_index(), 6)
363 def test_page_has_next(self):
364 self.assertTrue(self.p.page(3).has_next(), True)
366 def test_page_has_previous(self):
367 self.assertTrue(self.p.page(3).has_previous(), True)
369 def test_page_next_link(self):
370 self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
372 def test_page_previous_link(self):
373 self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
375 def test_on_start_page_repr(self):
376 self.assertEqual(repr(self.p.page(2)), '<Page 2>')
378 def test_on_start_has_no_next(self):
379 self.assertTrue(self.p.page(2).has_next(), False)
381 def test_on_start_has_previous(self):
382 self.assertTrue(self.p.page(2).has_previous(), True)
384 def test_on_start_has_next_link(self):
385 self.assertEqual(self.p.page(2).next_link(), '/bacon/page/3')
387 def test_on_start_has_previous_link(self):
388 self.assertEqual(self.p.page(2).previous_link(), '/bacon/page/1')
391 class MiddlewareTestCase(SimpleTestCase):
395 def test_get_page_in_request(self):
396 middleware = PaginationMiddleware()
397 request = DjangoHttpRequest()
398 middleware.process_request(request)
399 self.assertEqual(request.page(''), 1)