From b705301d9fa4a7b4904c369922344bd89a40ae9d Mon Sep 17 00:00:00 2001 From: Erwan Rouchet <rouchet@teklia.com> Date: Fri, 12 Jun 2020 10:01:25 +0200 Subject: [PATCH] Handle non-JSON responses on image check --- arkindex/images/models.py | 7 +++++- arkindex/images/tests/test_perform_check.py | 26 +++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/arkindex/images/models.py b/arkindex/images/models.py index ea93a760e9..a91dc4388d 100644 --- a/arkindex/images/models.py +++ b/arkindex/images/models.py @@ -6,6 +6,7 @@ from django.db.models.functions import Concat, Substr from django.utils.functional import cached_property from django.utils.text import slugify from enumfields import EnumField +from json import JSONDecodeError from arkindex.images.managers import ImageServerManager from arkindex.project.aws import S3FileMixin, S3FileStatus from arkindex.project.fields import StripSlashURLField, LStripTextField, MD5HashField @@ -221,7 +222,11 @@ class Image(S3FileMixin, IndexableModel): # Load info resp = requests.get(info_url, timeout=15, allow_redirects=True) resp.raise_for_status() - self.check_from_payload(resp.json()) + try: + payload = resp.json() + except JSONDecodeError: + raise ValueError('Server returned an invalid JSON document') + self.check_from_payload(payload) except Exception as e: logger.warning('Image check failed: {}'.format(str(e))) self.status = S3FileStatus.Error diff --git a/arkindex/images/tests/test_perform_check.py b/arkindex/images/tests/test_perform_check.py index c9ea3d3d7c..edda3f5b1f 100644 --- a/arkindex/images/tests/test_perform_check.py +++ b/arkindex/images/tests/test_perform_check.py @@ -23,10 +23,32 @@ class TestImagePerformCheck(FixtureTestCase): self.img.perform_check(raise_exc=True, save=False) self.assertEqual(self.img.status, S3FileStatus.Error) + @responses.activate + def test_empty(self): + """ + Test Image.perform_check fails when the server returns nothing + """ + responses.add(responses.GET, 'http://server/img1/info.json', status=200) + self.img.status = S3FileStatus.Unchecked + with self.assertRaisesRegex(ValueError, 'Server returned an invalid JSON document'): + self.img.perform_check(raise_exc=True, save=False) + self.assertEqual(self.img.status, S3FileStatus.Error) + + @responses.activate + def test_json(self): + """ + Test Image.perform_check fails when the server returns invalid JSON + """ + responses.add(responses.GET, 'http://server/img1/info.json', body='<blink>oh no</blink>') + self.img.status = S3FileStatus.Unchecked + with self.assertRaisesRegex(ValueError, 'Server returned an invalid JSON document'): + self.img.perform_check(raise_exc=True, save=False) + self.assertEqual(self.img.status, S3FileStatus.Error) + @responses.activate def test_required_items(self): """ - Test Image.perform_check fails on a HTTP error code + Test Image.perform_check fails when required items are missing from the JSON payload """ base_payload = { '@id': 'http://server/img1', @@ -38,7 +60,7 @@ class TestImagePerformCheck(FixtureTestCase): payload = base_payload.copy() del payload[key] responses.add(responses.GET, 'http://server/img1/info.json', json=payload) - with self.assertRaises(AssertionError, msg='Missing required properties'): + with self.assertRaisesRegex(AssertionError, 'Missing required properties'): self.img.perform_check(raise_exc=True, save=False) self.assertEqual(self.img.status, S3FileStatus.Error) -- GitLab