From f3225da1ddb33050fedfa23bf4a5d5d407fc72aa Mon Sep 17 00:00:00 2001 From: Erwan Rouchet <rouchet@teklia.com> Date: Thu, 13 Apr 2023 15:46:32 +0200 Subject: [PATCH] Support arbitrary job IDs in RetrieveJob and DestroyJob --- arkindex/project/api_v1.py | 2 +- arkindex/users/serializers.py | 2 +- arkindex/users/tests/test_jobs.py | 46 +++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/arkindex/project/api_v1.py b/arkindex/project/api_v1.py index aadc80a50f..c2292c2ac5 100644 --- a/arkindex/project/api_v1.py +++ b/arkindex/project/api_v1.py @@ -332,7 +332,7 @@ api = [ # Asynchronous jobs path('jobs/', JobList.as_view(), name='jobs-list'), - path('jobs/<uuid:pk>/', JobRetrieve.as_view(), name='jobs-retrieve'), + path('jobs/<path:pk>/', JobRetrieve.as_view(), name='jobs-retrieve'), # OpenAPI Schema path('openapi/', OpenApiSchemaView.as_view(), name='openapi-schema'), diff --git a/arkindex/users/serializers.py b/arkindex/users/serializers.py index 2deee821ba..b2112274be 100644 --- a/arkindex/users/serializers.py +++ b/arkindex/users/serializers.py @@ -230,7 +230,7 @@ class JobSerializer(serializers.Serializer): """ Serializers a RQ job. """ - id = serializers.UUIDField(read_only=True) + id = serializers.CharField(read_only=True) description = serializers.CharField(read_only=True) progress = serializers.FloatField(min_value=0, max_value=1, read_only=True, allow_null=True) status = serializers.SerializerMethodField() diff --git a/arkindex/users/tests/test_jobs.py b/arkindex/users/tests/test_jobs.py index 98e2c53bac..c06172b912 100644 --- a/arkindex/users/tests/test_jobs.py +++ b/arkindex/users/tests/test_jobs.py @@ -180,6 +180,34 @@ class TestJobs(FixtureAPITestCase): self.assertEqual(get_queue_mock().fetch_job.call_count, 1) self.assertEqual(get_queue_mock().fetch_job.call_args, call(self.user_mocked_job.id)) + @patch('arkindex.users.api.get_queue') + def test_retrieve_custom_id(self, get_queue_mock): + """ + Job IDs can be any string, including one with slashes, so we should allow any string in RetrieveJob + """ + job = MockedJob(user_id=self.user.id, id='a/b/c/d') + get_queue_mock.return_value.fetch_job.return_value = job + self.client.force_login(self.user) + + with self.assertNumQueries(2): + response = self.client.get(reverse('api:jobs-retrieve', kwargs={'pk': 'a/b/c/d'})) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + self.assertDictEqual(response.json(), { + 'id': 'a/b/c/d', + 'status': 'queued', + 'enqueued_at': '2020-01-01T13:37:42Z', + 'started_at': None, + 'ended_at': None, + 'progress': None, + 'description': 'something' + }) + + self.assertEqual(get_queue_mock.call_count, 1) + self.assertEqual(get_queue_mock.call_args, call('default')) + self.assertEqual(get_queue_mock().fetch_job.call_count, 1) + self.assertEqual(get_queue_mock().fetch_job.call_args, call('a/b/c/d')) + @patch('arkindex.users.api.get_queue') def test_retrieve_not_found(self, get_queue_mock): get_queue_mock.return_value.fetch_job.return_value = None @@ -300,3 +328,21 @@ class TestJobs(FixtureAPITestCase): self.assertEqual(get_queue_mock().fetch_job.call_count, 1) self.assertEqual(get_queue_mock().fetch_job.call_args, call(started_job.id)) self.assertFalse(started_job.delete.called) + + @patch('arkindex.users.api.get_queue') + def test_destroy_custom_id(self, get_queue_mock): + """ + Job IDs can be any string, including one with slashes, so we should allow any string in DestroyJob + """ + job = MockedJob(user_id=self.user.id, id='a/b/c/d') + get_queue_mock.return_value.fetch_job.return_value = job + self.client.force_login(self.user) + + with self.assertNumQueries(2): + response = self.client.delete(reverse('api:jobs-retrieve', kwargs={'pk': 'a/b/c/d'})) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + self.assertEqual(get_queue_mock.call_count, 1) + self.assertEqual(get_queue_mock().fetch_job.call_count, 1) + self.assertEqual(get_queue_mock().fetch_job.call_args, call('a/b/c/d')) + self.assertEqual(job.delete.call_count, 1) -- GitLab