1dc6d2c107c328b79a27d13c5f22f3f668628569
[django-pagination.git] / linaro_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
35 try:
36     from django.test import SimpleTestCase
37 except ImportError:  # Django 1.2 compatible
38     from django.test import TestCase as SimpleTestCase
39
40 from linaro_django_pagination.paginator import InfinitePaginator, FinitePaginator
41 from linaro_django_pagination.templatetags.pagination_tags import paginate
42 from linaro_django_pagination.middleware import PaginationMiddleware
43
44
45 class HttpRequest(DjangoHttpRequest):
46      page = lambda self, suffix: 1
47
48
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)
56
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)
63
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])
67
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])
71
72
73 class DefaultWindowTestCase(SimpleTestCase):
74     """
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
79     """
80     def setUp(self):
81         self.p = Paginator(range(31), 2)
82
83     def test_on_start_page_1(self):
84         # [1] 2 3 4 5 ... 15, 16
85         self.assertListEqual(
86             paginate({'paginator': self.p, 'page_obj': self.p.page(1)}, 2, 2)['pages'],
87             [1, 2, 3, 4, 5, None, 15, 16]
88         )
89
90     def test_on_start_page_2(self):
91         # 1 [2] 3 4 5 ... 15, 16
92         self.assertListEqual(
93             paginate({'paginator': self.p, 'page_obj': self.p.page(2)}, 2, 2)['pages'],
94             [1, 2, 3, 4, 5, None, 15, 16]
95         )
96
97     def test_on_start_page_3(self):
98         # 1 2 [3] 4 5 ... 15, 16
99         self.assertListEqual(
100             paginate({'paginator': self.p, 'page_obj': self.p.page(3)}, 2, 2)['pages'],
101             [1, 2, 3, 4, 5, None, 15, 16]
102         )
103
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])
109
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]
115         )
116
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]
122         )
123
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],
129         )
130
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]
136         )
137
138
139 class NoMarginTestCase(SimpleTestCase):
140     def setUp(self):
141         self.p = Paginator(range(31), 2)
142
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],
147         )
148
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],
153         )
154
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],
159         )
160
161
162 class ZeroWindowZeroMarginTestCase(SimpleTestCase):
163     """
164     Test paginate using window=0 and margin=0
165     """
166     def setUp(self):
167         self.p = Paginator(range(31), 2)
168
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'],
172             [1, None],
173         )
174
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'],
178             [None, 2, None],
179         )
180
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'],
184             [None, 3, None],
185         )
186
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'],
190             [None, 10, None],
191         )
192
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'],
196             [None, 14, None],
197         )
198
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'],
202             [None, 15, None],
203         )
204
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'],
208             [None, 16],
209         )
210
211
212 class SpecialTestCase(SimpleTestCase):
213     def test_middle_with_no_window_and_margin_1(self):
214         p = Paginator(range(31), 2)
215         self.assertListEqual(
216             paginate({'paginator': p, 'page_obj': p.page(5)}, 0, 1)['pages'],
217             [1, None, 5, None, 16],
218         )
219
220     def test_middle_with_no_window_and_margin_4(self):
221         p = Paginator(range(21), 2, 1)
222         self.assertListEqual(
223             paginate({'paginator': p, 'page_obj': p.page(1)}, 0, 4)['pages'],
224             [1, 2, 3, 4, None, 7, 8, 9, 10],
225         )
226
227
228 class TemplateRenderingTestCase(SimpleTestCase):
229     def test_default_tag_options(self):
230         t = Template("{% load pagination_tags %}{% autopaginate var %}{% paginate %}")
231         self.assertIn(
232             '<div class="pagination">',
233             t.render(Context({'var': range(21), 'request': HttpRequest()})),
234         )
235
236     def test_paginate_by_option(self):
237         t = Template("{% load pagination_tags %}{% autopaginate var 20 %}{% paginate %}")
238         self.assertIn(
239             '<div class="pagination">',
240             t.render(Context({'var': range(21), 'request': HttpRequest()})),
241         )
242
243     def test_orphans_option(self):
244         t = Template("{% load pagination_tags %}{% autopaginate var by %}{% paginate %}")
245         content = t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()}))
246         self.assertIn('<div class="pagination">', content)
247         self.assertIn('<a href="?page=2"', content)
248
249     def test_as_option(self):
250         t = Template("{% load pagination_tags %}{% autopaginate var by as foo %}{{ foo }}")
251         self.assertEqual(
252             t.render(Context({'var': range(21), 'by': 20, 'request': HttpRequest()})),
253             str(range(20)),
254         )
255
256     def test_multiple_pagination(self):
257         t = Template("{% load pagination_tags %}{% autopaginate var2 by as foo2 %}{% paginate %}"
258                      "{% autopaginate var by as foo %}{% paginate %}")
259         content = t.render(Context({'var': range(21), 'var2': range(50, 121), 'by': 20, 'request': HttpRequest()}))
260         self.assertIn('<div class="pagination">', content)
261         self.assertIn('<a href="?page_var2=2"', content)
262         self.assertIn('<a href="?page_var=2"', content)
263
264
265 class InfinitePaginatorTestCase(SimpleTestCase):
266     def setUp(self):
267         self.p = InfinitePaginator(range(20), 2, link_template='/bacon/page/%d')
268
269     def test_paginator_repr(self):
270         self.assertEqual(
271             repr(InfinitePaginator),
272             "<class 'linaro_django_pagination.paginator.InfinitePaginator'>",
273         )
274
275     def test_validate_number(self):
276         self.assertEqual(self.p.validate_number(2), 2)
277
278     def test_orphans(self):
279         self.assertEqual(self.p.orphans, 0)
280
281     def test_page_repr(self):
282         self.assertEqual(repr(self.p.page(3)), '<Page 3>')
283
284     def test_page_end_index(self):
285         self.assertEqual(self.p.page(3).end_index(), 6)
286
287     def test_page_has_next(self):
288         self.assertTrue(self.p.page(3).has_next(), True)
289
290     def test_page_has_previous(self):
291         self.assertTrue(self.p.page(3).has_previous(), True)
292
293     def test_page_next_link(self):
294         self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
295
296     def test_page_previous_link(self):
297         self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
298
299     def test_last_page_which_has_no_next_page(self):
300         self.assertFalse(self.p.page(10).has_next())
301
302     def test_first_page_which_has_no_previous_page(self):
303         self.assertFalse(self.p.page(1).has_previous())
304
305
306 class FinitePaginatorTestCase(SimpleTestCase):
307     def setUp(self):
308         self.p = FinitePaginator(range(20), 2, offset=10, link_template='/bacon/page/%d')
309
310     def test_repr(self):
311         self.assertEqual(
312             repr(FinitePaginator),
313             "<class 'linaro_django_pagination.paginator.FinitePaginator'>"
314         )
315
316     def test_validate_number(self):
317         self.assertEqual(self.p.validate_number(2), 2)
318
319     def test_orphans(self):
320         self.assertEqual(self.p.orphans, 0)
321
322     def test_page_repr(self):
323         self.assertEqual(repr(self.p.page(3)), '<Page 3>')
324
325     def test_page_start_index(self):
326         self.assertEqual(self.p.page(3).start_index(), 10)
327
328     def test_page_end(self):
329         self.assertEqual(self.p.page(3).end_index(), 6)
330
331     def test_page_has_next(self):
332         self.assertTrue(self.p.page(3).has_next(), True)
333
334     def test_page_has_previous(self):
335         self.assertTrue(self.p.page(3).has_previous(), True)
336
337     def test_page_next_link(self):
338         self.assertEqual(self.p.page(3).next_link(), '/bacon/page/4')
339
340     def test_page_previous_link(self):
341         self.assertEqual(self.p.page(3).previous_link(), '/bacon/page/2')
342
343     def test_on_start_page_repr(self):
344         self.assertEqual(repr(self.p.page(2)), '<Page 2>')
345
346     def test_on_start_has_no_next(self):
347         self.assertTrue(self.p.page(2).has_next(), False)
348
349     def test_on_start_has_previous(self):
350         self.assertTrue(self.p.page(2).has_previous(), True)
351
352     def test_on_start_has_next_link(self):
353         self.assertEqual(self.p.page(2).next_link(), '/bacon/page/3')
354
355     def test_on_start_has_previous_link(self):
356         self.assertEqual(self.p.page(2).previous_link(), '/bacon/page/1')
357
358
359 class MiddlewareTestCase(SimpleTestCase):
360     """
361     Test middleware
362     """
363     def test_get_page_in_request(self):
364         middleware = PaginationMiddleware()
365         request = DjangoHttpRequest()
366         middleware.process_request(request)
367         self.assertEqual(request.page(''), 1)