From 80ad757337da749c9468805b2fce22e566e2a0bf Mon Sep 17 00:00:00 2001
From: Jean-Baptiste <bleme@pm.me>
Date: Tue, 6 Aug 2019 11:09:12 +0200
Subject: [PATCH] update: use Link Headers for pagination

---
 README.md                           |  2 +-
 djangoldp/pagination.py             | 16 ++++++++++++++++
 djangoldp/tests/runner.py           |  5 +++++
 djangoldp/tests/tests_pagination.py | 28 ++++++++++++++++++++++++++++
 4 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 djangoldp/pagination.py
 create mode 100644 djangoldp/tests/tests_pagination.py

diff --git a/README.md b/README.md
index 80c0079b..433aa0a3 100644
--- a/README.md
+++ b/README.md
@@ -233,7 +233,7 @@ To enable pagination feature just add this configuration to the server `settings
 
 ```
 REST_FRAMEWORK = {
-    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
+    'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination',
     'PAGE_SIZE': 20
 }
 ```
diff --git a/djangoldp/pagination.py b/djangoldp/pagination.py
new file mode 100644
index 00000000..90386d27
--- /dev/null
+++ b/djangoldp/pagination.py
@@ -0,0 +1,16 @@
+from rest_framework.pagination import LimitOffsetPagination
+from rest_framework.response import Response
+
+
+class LDPPagination(LimitOffsetPagination):
+    def get_paginated_response(self, data):
+        next_url = self.get_next_link()
+        previous_url = self.get_previous_link()
+
+        links = []
+        for url, label in ((previous_url, 'prev'), (next_url, 'next')):
+            if url is not None:
+                links.append('<{}>; rel="{}"'.format(url, label))
+
+        headers = {'Link': ', '.join(links)} if links else {}
+        return Response(data, headers=headers)
diff --git a/djangoldp/tests/runner.py b/djangoldp/tests/runner.py
index 86c7a99b..2dd377fa 100644
--- a/djangoldp/tests/runner.py
+++ b/djangoldp/tests/runner.py
@@ -49,6 +49,10 @@ settings.configure(DEBUG=False,
                                    'djangoldp.tests',
                                    ),
                    SITE_URL='http://happy-dev.fr',
+                   REST_FRAMEWORK = {
+                       'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination',
+                       'PAGE_SIZE': 5
+                   },
                    )
 
 django.setup()
@@ -66,6 +70,7 @@ failures = test_runner.run_tests([
     'djangoldp.tests.tests_get',
     'djangoldp.tests.tests_delete',
     'djangoldp.tests.tests_sources',
+    'djangoldp.tests.tests_pagination',
     # 'djangoldp.tests.tests_temp'
 
 ])
diff --git a/djangoldp/tests/tests_pagination.py b/djangoldp/tests/tests_pagination.py
new file mode 100644
index 00000000..8e0cf5de
--- /dev/null
+++ b/djangoldp/tests/tests_pagination.py
@@ -0,0 +1,28 @@
+from rest_framework.test import APIRequestFactory, APIClient, APITestCase
+
+from djangoldp.tests.models import Post
+
+
+class TestPagination(APITestCase):
+
+    def setUp(self):
+        self.factory = APIRequestFactory()
+        self.client = APIClient()
+        for i in range(0, 10):
+            Post.objects.create(content="content {}".format(i))
+
+    def tearDown(self):
+        pass
+
+    def test_next(self):
+        response = self.client.get('/posts/', content_type='application/ld+json')
+        self.assertEqual(response.status_code, 200)
+        self.assertIn('link', response._headers)
+        self.assertEquals(response._headers['link'][1], '<http://testserver/posts/?limit=5&offset=5>; rel="next"')
+
+    def test_previous(self):
+        response = self.client.get('/posts/?offset=2&limit=2', content_type='application/ld+json')
+        self.assertEqual(response.status_code, 200)
+        self.assertIn('link', response._headers)
+        self.assertEquals(response._headers['link'][1],
+                          '<http://testserver/posts/?limit=2>; rel="prev", <http://testserver/posts/?limit=2&offset=4>; rel="next"')
-- 
GitLab