diff --git a/landingzones/tests/test_views_api.py b/landingzones/tests/test_views_api.py index 6282bcaa..d81548a9 100644 --- a/landingzones/tests/test_views_api.py +++ b/landingzones/tests/test_views_api.py @@ -61,7 +61,7 @@ def setUp(self): self.study = self.investigation.studies.first() self.assay = self.study.assays.first() # Create LandingZone - self.landing_zone = self.make_landing_zone( + self.zone = self.make_landing_zone( title=ZONE_TITLE, project=self.project, user=self.user, @@ -74,50 +74,79 @@ def setUp(self): class TestLandingZoneListAPIView(TestLandingZoneAPIViewsBase): """Tests for LandingZoneListAPIView""" - def test_get_owner(self): - """Test LandingZoneListAPIView get() as project owner""" - irods_backend = get_backend_api('omics_irods') - url = reverse( + def setUp(self): + super().setUp() + self.irods_backend = get_backend_api('omics_irods') + self.url = reverse( 'landingzones:api_list', kwargs={'project': self.project.sodar_uuid} ) - response = self.request_knox(url) + def test_get_owner(self): + """Test LandingZoneListAPIView GET as project owner""" + response = self.request_knox(self.url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) expected = { - 'title': self.landing_zone.title, + 'title': self.zone.title, 'project': str(self.project.sodar_uuid), 'user': self.get_serialized_user(self.user), 'assay': str(self.assay.sodar_uuid), - 'status': self.landing_zone.status, - 'status_info': self.landing_zone.status_info, + 'status': self.zone.status, + 'status_info': self.zone.status_info, 'status_locked': False, - 'date_modified': self.get_drf_datetime( - self.landing_zone.date_modified - ), - 'description': self.landing_zone.description, - 'user_message': self.landing_zone.user_message, - 'configuration': self.landing_zone.configuration, - 'config_data': self.landing_zone.config_data, - 'irods_path': irods_backend.get_path(self.landing_zone), - 'sodar_uuid': str(self.landing_zone.sodar_uuid), + 'date_modified': self.get_drf_datetime(self.zone.date_modified), + 'description': self.zone.description, + 'user_message': self.zone.user_message, + 'configuration': self.zone.configuration, + 'config_data': self.zone.config_data, + 'irods_path': self.irods_backend.get_path(self.zone), + 'sodar_uuid': str(self.zone.sodar_uuid), } self.assertEqual(json.loads(response.content)[0], expected) + def test_get_pagination(self): + """Test GET with pagination""" + url = self.url + '?page=1' + response = self.request_knox(url) + self.assertEqual(response.status_code, 200) + expected = { + 'count': 1, + 'next': None, + 'previous': None, + 'results': [ + { + 'title': self.zone.title, + 'project': str(self.project.sodar_uuid), + 'user': self.get_serialized_user(self.user), + 'assay': str(self.assay.sodar_uuid), + 'status': self.zone.status, + 'status_info': self.zone.status_info, + 'status_locked': False, + 'date_modified': self.get_drf_datetime( + self.zone.date_modified + ), + 'description': self.zone.description, + 'user_message': self.zone.user_message, + 'configuration': self.zone.configuration, + 'config_data': self.zone.config_data, + 'irods_path': self.irods_backend.get_path(self.zone), + 'sodar_uuid': str(self.zone.sodar_uuid), + } + ], + } + self.assertEqual(json.loads(response.content), expected) + def test_get_no_own_zones(self): - """Test LandingZoneListAPIView get() as user with no own zones""" - url = reverse( - 'landingzones:api_list', kwargs={'project': self.project.sodar_uuid} - ) + """Test GET as user with no own zones""" response = self.request_knox( - url, token=self.get_token(self.user_contributor) + self.url, token=self.get_token(self.user_contributor) ) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) def test_get_finished_default(self): - """Test get() with finished zone and no finished parameter""" + """Test GET with finished zone and no finished parameter""" self.make_landing_zone( title=ZONE_TITLE + '_moved', project=self.project, @@ -126,19 +155,16 @@ def test_get_finished_default(self): description=ZONE_DESC, status=ZONE_STATUS_MOVED, ) - url = reverse( - 'landingzones:api_list', kwargs={'project': self.project.sodar_uuid} - ) - response = self.request_knox(url) + response = self.request_knox(self.url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) self.assertEqual( json.loads(response.content)[0]['sodar_uuid'], - str(self.landing_zone.sodar_uuid), + str(self.zone.sodar_uuid), ) def test_get_finished_false(self): - """Test get() with finished zone and finished=0""" + """Test GET with finished zone and finished=0""" self.make_landing_zone( title=ZONE_TITLE + '_moved', project=self.project, @@ -147,23 +173,17 @@ def test_get_finished_false(self): description=ZONE_DESC, status=ZONE_STATUS_MOVED, ) - url = ( - reverse( - 'landingzones:api_list', - kwargs={'project': self.project.sodar_uuid}, - ) - + '?finished=0' - ) + url = self.url + '?finished=0' response = self.request_knox(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) self.assertEqual( json.loads(response.content)[0]['sodar_uuid'], - str(self.landing_zone.sodar_uuid), + str(self.zone.sodar_uuid), ) def test_get_finished_true(self): - """Test get() with finished zone and finished=1""" + """Test GET with finished zone and finished=1""" self.make_landing_zone( title=ZONE_TITLE + '_moved', project=self.project, @@ -172,13 +192,7 @@ def test_get_finished_true(self): description=ZONE_DESC, status=ZONE_STATUS_MOVED, ) - url = ( - reverse( - 'landingzones:api_list', - kwargs={'project': self.project.sodar_uuid}, - ) - + '?finished=1' - ) + url = self.url + '?finished=1' response = self.request_knox(url) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 2) @@ -188,42 +202,40 @@ class TestLandingZoneRetrieveAPIView(TestLandingZoneAPIViewsBase): """Tests for LandingZoneRetrieveAPIView""" def test_get(self): - """Test LandingZoneRetrieveAPIView get() as zone owner""" + """Test LandingZoneRetrieveAPIView GET as zone owner""" irods_backend = get_backend_api('omics_irods') url = reverse( 'landingzones:api_retrieve', - kwargs={'landingzone': self.landing_zone.sodar_uuid}, + kwargs={'landingzone': self.zone.sodar_uuid}, ) response = self.request_knox(url) self.assertEqual(response.status_code, 200) expected = { - 'title': self.landing_zone.title, + 'title': self.zone.title, 'project': str(self.project.sodar_uuid), 'user': self.get_serialized_user(self.user), 'assay': str(self.assay.sodar_uuid), - 'status': self.landing_zone.status, - 'status_info': self.landing_zone.status_info, + 'status': self.zone.status, + 'status_info': self.zone.status_info, 'status_locked': False, - 'date_modified': self.get_drf_datetime( - self.landing_zone.date_modified - ), - 'description': self.landing_zone.description, - 'user_message': self.landing_zone.user_message, - 'configuration': self.landing_zone.configuration, - 'config_data': self.landing_zone.config_data, - 'irods_path': irods_backend.get_path(self.landing_zone), - 'sodar_uuid': str(self.landing_zone.sodar_uuid), + 'date_modified': self.get_drf_datetime(self.zone.date_modified), + 'description': self.zone.description, + 'user_message': self.zone.user_message, + 'configuration': self.zone.configuration, + 'config_data': self.zone.config_data, + 'irods_path': irods_backend.get_path(self.zone), + 'sodar_uuid': str(self.zone.sodar_uuid), } self.assertEqual(json.loads(response.content), expected) def test_get_locked(self): - """Test get() with locked landing zone status""" - self.landing_zone.status = ZONE_STATUS_MOVING - self.landing_zone.save() + """Test GET with locked landing zone status""" + self.zone.status = ZONE_STATUS_MOVING + self.zone.save() url = reverse( 'landingzones:api_retrieve', - kwargs={'landingzone': self.landing_zone.sodar_uuid}, + kwargs={'landingzone': self.zone.sodar_uuid}, ) response = self.request_knox(url) self.assertEqual(response.status_code, 200) @@ -233,17 +245,20 @@ def test_get_locked(self): class TestLandingZoneUpdateAPIView(TestLandingZoneAPIViewsBase): """Tests for LandingZoneUpdateAPIView""" - def test_patch(self): - """Test LandingZoneUpdateAPIView patch() as zone owner""" - url = reverse( + def setUp(self): + super().setUp() + self.url = reverse( 'landingzones:api_update', - kwargs={'landingzone': self.landing_zone.sodar_uuid}, + kwargs={'landingzone': self.zone.sodar_uuid}, ) + + def test_patch(self): + """Test LandingZoneUpdateAPIView PATCH as zone owner""" data = { 'description': 'New description', 'user_message': 'New user message', } - response = self.request_knox(url, method='PATCH', data=data) + response = self.request_knox(self.url, method='PATCH', data=data) self.assertEqual(response.status_code, 200) self.assertEqual( json.loads(response.content)['description'], 'New description' @@ -253,26 +268,18 @@ def test_patch(self): ) def test_patch_title(self): - """Test updating title with patch() (should fail)""" - url = reverse( - 'landingzones:api_update', - kwargs={'landingzone': self.landing_zone.sodar_uuid}, - ) + """Test PATCH to update title (should fail)""" data = {'title': 'New title'} - response = self.request_knox(url, method='PATCH', data=data) + response = self.request_knox(self.url, method='PATCH', data=data) self.assertEqual(response.status_code, 400) def test_put(self): - """Test LandingZoneUpdateAPIView put() as zone owner""" - url = reverse( - 'landingzones:api_update', - kwargs={'landingzone': self.landing_zone.sodar_uuid}, - ) + """Test PUT as zone owner""" data = { 'description': 'New description', 'user_message': 'New user message', } - response = self.request_knox(url, method='PUT', data=data) + response = self.request_knox(self.url, method='PUT', data=data) self.assertEqual(response.status_code, 200) self.assertEqual( json.loads(response.content)['description'], 'New description' @@ -282,11 +289,7 @@ def test_put(self): ) def test_put_title(self): - """Test updating title with put() (should fail)""" - url = reverse( - 'landingzones:api_update', - kwargs={'landingzone': self.landing_zone.sodar_uuid}, - ) + """Test PUT to update title (should fail)""" data = {'title': 'New title'} - response = self.request_knox(url, method='PUT', data=data) + response = self.request_knox(self.url, method='PUT', data=data) self.assertEqual(response.status_code, 400) diff --git a/landingzones/views_api.py b/landingzones/views_api.py index 74865264..30c08918 100644 --- a/landingzones/views_api.py +++ b/landingzones/views_api.py @@ -23,6 +23,7 @@ from projectroles.views_api import ( SODARAPIBaseProjectMixin, SODARAPIGenericProjectMixin, + SODARPageNumberPagination, ) # Samplesheets dependency @@ -119,6 +120,10 @@ class ZoneListAPIView( finished (meaning moved or deleted) zones if the "finished" parameter is set. + Supports optional pagination for listing by providing the ``page`` query + string. This will return results in the Django Rest Framework + ``PageNumberPagination`` format. + **URL:** ``/landingzones/api/list/{Project.sodar_uuid}?finished={integer}`` **Methods:** ``GET`` @@ -126,10 +131,12 @@ class ZoneListAPIView( **Parameters:** - ``finished``: Include finished zones if 1 (integer) + - ``page``: Page number for paginated results (int, optional) **Returns:** List of landing zone details (see ``ZoneRetrieveAPIView``) """ + pagination_class = SODARPageNumberPagination permission_required = 'landingzones.view_zone_own' serializer_class = LandingZoneSerializer