diff --git a/arkindex/images/models.py b/arkindex/images/models.py index ea93a760e913699ed052dc001b21f5190d214559..a91dc4388d04f5851b3e4d38c1bcf56548522103 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 c9ea3d3d7c42edb458471c1e183906de76fdd47f..edda3f5b1f7a98725db480b26437c5810a3ba075 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)