diff --git a/arkindex/project/api_v1.py b/arkindex/project/api_v1.py index aadc80a50fca8c014c5401c6053f4a1f2b055c16..c2292c2ac59b02e661af3160a7c3ffff76418676 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 2deee821babcea8e7df01f4333d5ea44231a279d..b2112274be3466adc702bb42839aea2202f2ba11 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 98e2c53bac306484276ba65996b5cb5fecf5e3c1..c06172b9129c28e9f1e341eb37cd0a7a92a25885 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)