diff --git a/wagtail/wagtailimages/tests/test_admin_views.py b/wagtail/wagtailimages/tests/test_admin_views.py index 3b73fd7e6..7eea7ed17 100644 --- a/wagtail/wagtailimages/tests/test_admin_views.py +++ b/wagtail/wagtailimages/tests/test_admin_views.py @@ -283,6 +283,11 @@ class TestImageEditView(TestCase, WagtailTestUtils): file=get_test_image_file(), ) + self.storage = self.image.file.storage + + def update_from_db(self): + self.image = Image.objects.get(pk=self.image.pk) + def get(self, params={}): return self.client.get(reverse('wagtailimages:edit', args=(self.image.id,)), params) @@ -327,9 +332,8 @@ class TestImageEditView(TestCase, WagtailTestUtils): # Should redirect back to index self.assertRedirects(response, reverse('wagtailimages:index')) - # Check that the image was edited - image = Image.objects.get(id=self.image.id) - self.assertEqual(image.title, "Edited") + self.update_from_db() + self.assertEqual(self.image.title, "Edited") def test_edit_with_new_image_file(self): file_content = get_test_image_file().file.getvalue() @@ -346,9 +350,8 @@ class TestImageEditView(TestCase, WagtailTestUtils): # Should redirect back to index self.assertRedirects(response, reverse('wagtailimages:index')) - # Check that the image file size changed (assume it changed to the correct value) - image = Image.objects.get(id=self.image.id) - self.assertNotEqual(image.file_size, 100000) + self.update_from_db() + self.assertNotEqual(self.image.file_size, 100000) @override_settings(DEFAULT_FILE_STORAGE='wagtail.tests.dummy_external_storage.DummyExternalStorage') def test_edit_with_new_image_file_and_external_storage(self): @@ -366,9 +369,8 @@ class TestImageEditView(TestCase, WagtailTestUtils): # Should redirect back to index self.assertRedirects(response, reverse('wagtailimages:index')) - # Check that the image file size changed (assume it changed to the correct value) - image = Image.objects.get(id=self.image.id) - self.assertNotEqual(image.file_size, 100000) + self.update_from_db() + self.assertNotEqual(self.image.file_size, 100000) def test_with_missing_image_file(self): self.image.file.delete(False) @@ -377,6 +379,86 @@ class TestImageEditView(TestCase, WagtailTestUtils): self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'wagtailimages/images/edit.html') + def get_content(self, f=None): + if f is None: + f = self.image.file + try: + if f.closed: + f.open('rb') + return f.read() + finally: + f.close() + + def test_reupload_same_name(self): + """ + Checks that reuploading the image file with the same file name + changes the file name, to avoid browser cache issues (see #3817). + """ + old_file = self.image.file + old_size = self.image.file_size + old_data = self.get_content() + + old_rendition = self.image.get_rendition('fill-5x5') + old_rendition_data = self.get_content(old_rendition.file) + + new_name = self.image.filename + new_file = SimpleUploadedFile( + new_name, get_test_image_file(colour='red').file.getvalue()) + new_size = new_file.size + + response = self.post({ + 'title': self.image.title, 'file': new_file, + }) + self.assertRedirects(response, reverse('wagtailimages:index')) + self.update_from_db() + self.assertFalse(self.storage.exists(old_file.name)) + self.assertTrue(self.storage.exists(self.image.file.name)) + self.assertNotEqual(self.image.file.name, + 'original_images/' + new_name) + self.assertNotEqual(self.image.file_size, old_size) + self.assertEqual(self.image.file_size, new_size) + self.assertNotEqual(self.get_content(), old_data) + + new_rendition = self.image.get_rendition('fill-5x5') + self.assertNotEqual(old_rendition.file.name, new_rendition.file.name) + self.assertNotEqual(self.get_content(new_rendition.file), + old_rendition_data) + + def test_reupload_different_name(self): + """ + Checks that reuploading the image file with a different file name + correctly uses the new file name. + """ + old_file = self.image.file + old_size = self.image.file_size + old_data = self.get_content() + + old_rendition = self.image.get_rendition('fill-5x5') + old_rendition_data = self.get_content(old_rendition.file) + + new_name = 'test_reupload_different_name.png' + new_file = SimpleUploadedFile( + new_name, get_test_image_file(colour='red').file.getvalue()) + new_size = new_file.size + + response = self.post({ + 'title': self.image.title, 'file': new_file, + }) + self.assertRedirects(response, reverse('wagtailimages:index')) + self.update_from_db() + self.assertFalse(self.storage.exists(old_file.name)) + self.assertTrue(self.storage.exists(self.image.file.name)) + self.assertEqual(self.image.file.name, + 'original_images/' + new_name) + self.assertNotEqual(self.image.file_size, old_size) + self.assertEqual(self.image.file_size, new_size) + self.assertNotEqual(self.get_content(), old_data) + + new_rendition = self.image.get_rendition('fill-5x5') + self.assertNotEqual(old_rendition.file.name, new_rendition.file.name) + self.assertNotEqual(self.get_content(new_rendition.file), + old_rendition_data) + class TestImageDeleteView(TestCase, WagtailTestUtils): def setUp(self): diff --git a/wagtail/wagtailimages/views/images.py b/wagtail/wagtailimages/views/images.py index 81ad7e774..28a019595 100644 --- a/wagtail/wagtailimages/views/images.py +++ b/wagtail/wagtailimages/views/images.py @@ -99,6 +99,12 @@ def edit(request, image_id): original_file = image.file form = ImageForm(request.POST, request.FILES, instance=image, user=request.user) if form.is_valid(): + if 'file' in form.changed_data: + # Set new image file size + image.file_size = image.file.size + + form.save() + if 'file' in form.changed_data: # if providing a new image file, delete the old one and all renditions. # NB Doing this via original_file.delete() clears the file field, @@ -106,11 +112,6 @@ def edit(request, image_id): original_file.storage.delete(original_file.name) image.renditions.all().delete() - # Set new image file size - image.file_size = image.file.size - - form.save() - # Reindex the image to make sure all tags are indexed search_index.insert_or_update_object(image)