|
@@ -1,3 +1,5 @@
|
|
|
+import re
|
|
|
+
|
|
|
from django.conf import settings
|
|
|
from django.core.exceptions import ValidationError
|
|
|
from django.core.management import call_command
|
|
@@ -42,15 +44,78 @@ class AuthenticatedRRSetTestCase(AuthenticatedRRSetBaseTestCase):
|
|
|
self.assertStatus(response, status.HTTP_200_OK)
|
|
|
self.assertEqual(len(response.data), 1, response.data)
|
|
|
|
|
|
+ def test_retrieve_my_rr_sets_pagination(self):
|
|
|
+ def convert_links(links):
|
|
|
+ mapping = {}
|
|
|
+ for link in links.split(', '):
|
|
|
+ _url, label = link.split('; ')
|
|
|
+ label = re.search('rel="(.*)"', label).group(1)
|
|
|
+ _url = _url[1:-1]
|
|
|
+ assert label not in mapping
|
|
|
+ mapping[label] = _url
|
|
|
+ return mapping
|
|
|
+
|
|
|
+ def assertPaginationResponse(response, expected_length, expected_directional_links=[]):
|
|
|
+ self.assertStatus(response, status.HTTP_200_OK)
|
|
|
+ self.assertEqual(len(response.data), expected_length)
|
|
|
+
|
|
|
+ _links = convert_links(response['Link'])
|
|
|
+ self.assertEqual(len(_links), len(expected_directional_links) + 1) # directional links, plus "first"
|
|
|
+ self.assertTrue(_links['first'].endswith('/?cursor='))
|
|
|
+ for directional_link in expected_directional_links:
|
|
|
+ self.assertEqual(_links['first'].find('/?cursor='), _links[directional_link].find('/?cursor='))
|
|
|
+ self.assertTrue(len(_links[directional_link]) > len(_links['first']))
|
|
|
+
|
|
|
+ # Prepare extra records so that we get three pages (total: n + 1)
|
|
|
+ n = int(settings.REST_FRAMEWORK['PAGE_SIZE'] * 2.5)
|
|
|
+ RRset.objects.bulk_create(
|
|
|
+ [RRset(domain=self.my_domain, subname=str(i), ttl=123, type='A') for i in range(n)]
|
|
|
+ )
|
|
|
+
|
|
|
+ # No pagination
|
|
|
+ response = self.client.get_rr_sets(self.my_domain.name)
|
|
|
+ self.assertStatus(response, status.HTTP_400_BAD_REQUEST)
|
|
|
+ self.assertEqual(response.data['detail'],
|
|
|
+ f'Pagination required. You can query up to {settings.REST_FRAMEWORK["PAGE_SIZE"]} items at a time ({n+1} total). '
|
|
|
+ 'Please use the `first` page link (see Link header).')
|
|
|
+ links = convert_links(response['Link'])
|
|
|
+ self.assertEqual(len(links), 1)
|
|
|
+ self.assertTrue(links['first'].endswith('/?cursor='))
|
|
|
+
|
|
|
+ # First page
|
|
|
+ url = links['first']
|
|
|
+ response = self.client.get(url)
|
|
|
+ assertPaginationResponse(response, settings.REST_FRAMEWORK['PAGE_SIZE'], ['next'])
|
|
|
+
|
|
|
+ # Next
|
|
|
+ url = convert_links(response['Link'])['next']
|
|
|
+ response = self.client.get(url)
|
|
|
+ assertPaginationResponse(response, settings.REST_FRAMEWORK['PAGE_SIZE'], ['next', 'prev'])
|
|
|
+ data_next = response.data.copy()
|
|
|
+
|
|
|
+ # Next-next (last) page
|
|
|
+ url = convert_links(response['Link'])['next']
|
|
|
+ response = self.client.get(url)
|
|
|
+ assertPaginationResponse(response, n/5 + 1, ['prev'])
|
|
|
+
|
|
|
+ # Prev
|
|
|
+ url = convert_links(response['Link'])['prev']
|
|
|
+ response = self.client.get(url)
|
|
|
+ assertPaginationResponse(response, settings.REST_FRAMEWORK['PAGE_SIZE'], ['next', 'prev'])
|
|
|
+
|
|
|
+ # Make sure that one step forward equals two steps forward and one step back
|
|
|
+ self.assertEqual(response.data, data_next)
|
|
|
+
|
|
|
def test_retrieve_other_rr_sets(self):
|
|
|
self.assertStatus(self.client.get_rr_sets(self.other_domain.name), status.HTTP_404_NOT_FOUND)
|
|
|
self.assertStatus(self.client.get_rr_sets(self.other_domain.name, subname='test'), status.HTTP_404_NOT_FOUND)
|
|
|
self.assertStatus(self.client.get_rr_sets(self.other_domain.name, type='A'), status.HTTP_404_NOT_FOUND)
|
|
|
|
|
|
def test_retrieve_my_rr_sets_filter(self):
|
|
|
- response = self.client.get_rr_sets(self.my_rr_set_domain.name)
|
|
|
+ response = self.client.get_rr_sets(self.my_rr_set_domain.name, query='?cursor=')
|
|
|
self.assertStatus(response, status.HTTP_200_OK)
|
|
|
- self.assertEqual(len(response.data), len(self._test_rr_sets()))
|
|
|
+ expected_number_of_rrsets = min(len(self._test_rr_sets()), settings.REST_FRAMEWORK['PAGE_SIZE'])
|
|
|
+ self.assertEqual(len(response.data), expected_number_of_rrsets)
|
|
|
|
|
|
for subname in self.SUBNAMES:
|
|
|
response = self.client.get_rr_sets(self.my_rr_set_domain.name, subname=subname)
|