1import os 2import unittest 3 4from django import forms, template 5from django.conf import settings 6from django.core.exceptions import ImproperlyConfigured 7from django.test import TestCase, override_settings 8from django.urls import reverse 9from taggit.forms import TagField, TagWidget 10 11from wagtail.images import get_image_model, get_image_model_string 12from wagtail.images.fields import WagtailImageField 13from wagtail.images.formats import Format, get_image_format, register_image_format 14from wagtail.images.forms import get_image_form 15from wagtail.images.models import Image as WagtailImage 16from wagtail.images.rect import Rect, Vector 17from wagtail.images.utils import generate_signature, verify_signature 18from wagtail.images.views.serve import ServeView 19from wagtail.tests.testapp.models import CustomImage, CustomImageFilePath 20from wagtail.tests.utils import WagtailTestUtils 21 22from .utils import Image, get_test_image_file 23 24 25try: 26 import sendfile # noqa 27 sendfile_mod = True 28except ImportError: 29 sendfile_mod = False 30 31 32class TestImageTag(TestCase): 33 def setUp(self): 34 # Create an image for running tests on 35 self.image = Image.objects.create( 36 title="Test image", 37 file=get_test_image_file(), 38 ) 39 40 def render_image_tag(self, image, filter_spec): 41 temp = template.Template('{% load wagtailimages_tags %}{% image image_obj ' + filter_spec + '%}') 42 context = template.Context({'image_obj': image}) 43 return temp.render(context) 44 45 def test_image_tag(self): 46 result = self.render_image_tag(self.image, 'width-400') 47 48 # Check that all the required HTML attributes are set 49 self.assertTrue('width="400"' in result) 50 self.assertTrue('height="300"' in result) 51 self.assertTrue('alt="Test image"' in result) 52 53 def test_image_tag_none(self): 54 result = self.render_image_tag(None, "width-500") 55 self.assertEqual(result, '') 56 57 def test_image_tag_wrong_type(self): 58 with self.assertRaises(ValueError): 59 self.render_image_tag("foobar", "width-500") 60 61 def render_image_tag_as(self, image, filter_spec): 62 temp = template.Template( 63 '{% load wagtailimages_tags %}{% image image_obj ' + filter_spec 64 + ' as test_img %}<img {{ test_img.attrs }} />' 65 ) 66 context = template.Context({'image_obj': image}) 67 return temp.render(context) 68 69 def test_image_tag_attrs(self): 70 result = self.render_image_tag_as(self.image, 'width-400') 71 72 # Check that all the required HTML attributes are set 73 self.assertTrue('width="400"' in result) 74 self.assertTrue('height="300"' in result) 75 self.assertTrue('alt="Test image"' in result) 76 77 def render_image_tag_with_extra_attributes(self, image, title): 78 temp = template.Template( 79 '{% load wagtailimages_tags %}{% image image_obj width-400 \ 80 class="photo" title=title|lower alt="Alternate" %}' 81 ) 82 context = template.Context({'image_obj': image, 'title': title}) 83 return temp.render(context) 84 85 def test_image_tag_with_extra_attributes(self): 86 result = self.render_image_tag_with_extra_attributes(self.image, 'My Wonderful Title') 87 88 # Check that all the required HTML attributes are set 89 self.assertTrue('width="400"' in result) 90 self.assertTrue('height="300"' in result) 91 self.assertTrue('class="photo"' in result) 92 self.assertTrue('alt="Alternate"' in result) 93 self.assertTrue('title="my wonderful title"' in result) 94 95 def render_image_tag_with_filters(self, image): 96 temp = template.Template( 97 '{% load wagtailimages_tags %}{% image image_primary|default:image_alternate width-400 %}' 98 ) 99 context = template.Context({'image_primary': None, 'image_alternate': image}) 100 return temp.render(context) 101 102 def test_image_tag_with_filters(self): 103 result = self.render_image_tag_with_filters(self.image) 104 self.assertTrue('width="400"' in result) 105 self.assertTrue('height="300"' in result) 106 107 def test_image_tag_with_chained_filters(self): 108 result = self.render_image_tag(self.image, 'fill-200x200 height-150') 109 self.assertTrue('width="150"' in result) 110 self.assertTrue('height="150"' in result) 111 112 def test_filter_specs_must_match_allowed_pattern(self): 113 with self.assertRaises(template.TemplateSyntaxError): 114 self.render_image_tag(self.image, 'fill-200x200|height-150') 115 116 with self.assertRaises(template.TemplateSyntaxError): 117 self.render_image_tag(self.image, 'fill-800x600 alt"test"') 118 119 def test_context_may_only_contain_one_argument(self): 120 with self.assertRaises(template.TemplateSyntaxError): 121 temp = template.Template( 122 '{% load wagtailimages_tags %}{% image image_obj fill-200x200' 123 ' as test_img this_one_should_not_be_there %}<img {{ test_img.attrs }} />' 124 ) 125 context = template.Context({'image_obj': self.image}) 126 temp.render(context) 127 128 def test_no_image_filter_provided(self): 129 # if image template gets the image but no filters 130 with self.assertRaises(template.TemplateSyntaxError): 131 temp = template.Template( 132 '{% load wagtailimages_tags %}{% image image_obj %}' 133 ) 134 context = template.Context({'image_obj': self.image}) 135 temp.render(context) 136 137 def test_no_image_filter_provided_when_using_as(self): 138 # if image template gets the image but no filters 139 with self.assertRaises(template.TemplateSyntaxError): 140 temp = template.Template( 141 '{% load wagtailimages_tags %}{% image image_obj as foo %}' 142 ) 143 context = template.Context({'image_obj': self.image}) 144 temp.render(context) 145 146 def test_no_image_filter_provided_but_attributes_provided(self): 147 # if image template gets the image but no filters 148 with self.assertRaises(template.TemplateSyntaxError): 149 temp = template.Template( 150 '{% load wagtailimages_tags %}{% image image_obj class="cover-image"%}' 151 ) 152 context = template.Context({'image_obj': self.image}) 153 temp.render(context) 154 155 def render_image_url_tag(self, image, view_name): 156 temp = template.Template( 157 '{% load wagtailimages_tags %}{% image_url image_obj "width-400" "' + view_name + '" %}' 158 ) 159 context = template.Context({'image_obj': image}) 160 return temp.render(context) 161 162 def test_image_url(self): 163 result = self.render_image_url_tag(self.image, 'wagtailimages_serve') 164 self.assertRegex( 165 result, 166 '/images/.*/width-400/{}'.format(self.image.file.name.split('/')[-1]), 167 ) 168 169 def test_image_url_custom_view(self): 170 result = self.render_image_url_tag(self.image, 'wagtailimages_serve_custom_view') 171 172 self.assertRegex( 173 result, 174 '/testimages/custom_view/.*/width-400/{}'.format(self.image.file.name.split('/')[-1]), 175 ) 176 177 def test_image_url_no_imageserve_view_added(self): 178 # if image_url tag is used, but the image serve view was not defined. 179 with self.assertRaises(ImproperlyConfigured): 180 temp = template.Template( 181 '{% load wagtailimages_tags %}{% image_url image_obj "width-400" "mynonexistingimageserve_view" %}' 182 ) 183 context = template.Context({'image_obj': self.image}) 184 temp.render(context) 185 186 187class TestMissingImage(TestCase): 188 """ 189 Missing image files in media/original_images should be handled gracefully, to cope with 190 pulling live databases to a development instance without copying the corresponding image files. 191 In this case, it's acceptable to render broken images, but not to fail rendering the page outright. 192 """ 193 fixtures = ['test.json'] 194 195 def test_image_tag_with_missing_image(self): 196 # the page /events/christmas/ has a missing image as the feed image 197 response = self.client.get('/events/christmas/') 198 self.assertContains( 199 response, 200 '<img src="/media/not-found" width="0" height="0" alt="A missing image" class="feed-image">', 201 html=True 202 ) 203 204 def test_rich_text_with_missing_image(self): 205 # the page /events/final-event/ has a missing image in the rich text body 206 response = self.client.get('/events/final-event/') 207 self.assertContains( 208 response, 209 '<img class="richtext-image full-width" src="/media/not-found" \ 210 width="0" height="0" alt="where did my image go?">', 211 html=True 212 ) 213 214 215class TestFormat(TestCase, WagtailTestUtils): 216 def setUp(self): 217 # test format 218 self.format = Format( 219 'test name', 220 'test label', 221 'test classnames', 222 'original' 223 ) 224 # test image 225 self.image = Image.objects.create( 226 title="Test image", 227 file=get_test_image_file(), 228 ) 229 230 def test_editor_attributes(self): 231 result = self.format.editor_attributes( 232 self.image, 233 'test alt text' 234 ) 235 self.assertEqual(result, 236 {'data-alt': 'test alt text', 'data-embedtype': 'image', 237 'data-format': 'test name', 'data-id': self.image.pk}) 238 239 def test_image_to_editor_html(self): 240 result = self.format.image_to_editor_html( 241 self.image, 242 'test alt text' 243 ) 244 self.assertTagInHTML( 245 '<img data-embedtype="image" data-id="%d" data-format="test name" ' 246 'data-alt="test alt text" class="test classnames" ' 247 'width="640" height="480" alt="test alt text" >' % self.image.pk, 248 result, allow_extra_attrs=True) 249 250 def test_image_to_editor_html_with_quoting(self): 251 result = self.format.image_to_editor_html( 252 self.image, 253 'Arthur "two sheds" Jackson' 254 ) 255 expected_html = ( 256 '<img data-embedtype="image" data-id="%d" data-format="test name" ' 257 'data-alt="Arthur "two sheds" Jackson" class="test classnames" ' 258 'width="640" height="480" alt="Arthur "two sheds" Jackson" >' 259 % self.image.pk 260 ) 261 self.assertTagInHTML(expected_html, result, allow_extra_attrs=True) 262 263 def test_image_to_html_no_classnames(self): 264 self.format.classnames = None 265 result = self.format.image_to_html(self.image, 'test alt text') 266 self.assertTagInHTML( 267 '<img width="640" height="480" alt="test alt text">', result, allow_extra_attrs=True) 268 self.format.classnames = 'test classnames' 269 270 def test_image_to_html_with_quoting(self): 271 result = self.format.image_to_html(self.image, 'Arthur "two sheds" Jackson') 272 self.assertTagInHTML( 273 '<img class="test classnames" width="640" height="480" ' 274 'alt="Arthur "two sheds" Jackson">', result, allow_extra_attrs=True) 275 276 def test_get_image_format(self): 277 register_image_format(self.format) 278 result = get_image_format('test name') 279 self.assertEqual(result, self.format) 280 281 282class TestSignatureGeneration(TestCase): 283 def test_signature_generation(self): 284 self.assertEqual(generate_signature(100, 'fill-800x600'), 'xnZOzQyUg6pkfciqcfRJRosOrGg=') 285 286 def test_signature_verification(self): 287 self.assertTrue(verify_signature('xnZOzQyUg6pkfciqcfRJRosOrGg=', 100, 'fill-800x600')) 288 289 def test_signature_changes_on_image_id(self): 290 self.assertFalse(verify_signature('xnZOzQyUg6pkfciqcfRJRosOrGg=', 200, 'fill-800x600')) 291 292 def test_signature_changes_on_filter_spec(self): 293 self.assertFalse(verify_signature('xnZOzQyUg6pkfciqcfRJRosOrGg=', 100, 'fill-800x700')) 294 295 296class TestFrontendServeView(TestCase): 297 def setUp(self): 298 # Create an image for running tests on 299 self.image = Image.objects.create( 300 title="Test image", 301 file=get_test_image_file(), 302 ) 303 304 def test_get(self): 305 """ 306 Test a valid GET request to the view 307 """ 308 # Generate signature 309 signature = generate_signature(self.image.id, 'fill-800x600') 310 311 # Get the image 312 response = self.client.get(reverse('wagtailimages_serve', args=(signature, self.image.id, 'fill-800x600'))) 313 314 # Check response 315 self.assertEqual(response.status_code, 200) 316 self.assertTrue(response.streaming) 317 self.assertEqual(response['Content-Type'], 'image/png') 318 319 def test_get_with_extra_component(self): 320 """ 321 Test that a filename can be optionally added to the end of the URL. 322 """ 323 # Generate signature 324 signature = generate_signature(self.image.id, 'fill-800x600') 325 326 # Get the image 327 response = self.client.get(reverse('wagtailimages_serve', args=(signature, self.image.id, 'fill-800x600')) + 'test.png') 328 329 # Check response 330 self.assertEqual(response.status_code, 200) 331 self.assertTrue(response.streaming) 332 self.assertEqual(response['Content-Type'], 'image/png') 333 334 def test_get_with_too_many_extra_components(self): 335 """ 336 A filename can be appended to the end of the URL, but it must not contain a '/' 337 """ 338 # Generate signature 339 signature = generate_signature(self.image.id, 'fill-800x600') 340 341 # Get the image 342 response = self.client.get(reverse('wagtailimages_serve', args=(signature, self.image.id, 'fill-800x600')) + 'test/test.png') 343 344 # URL pattern should not match 345 self.assertEqual(response.status_code, 404) 346 347 def test_get_with_serve_action(self): 348 signature = generate_signature(self.image.id, 'fill-800x600') 349 response = self.client.get(reverse('wagtailimages_serve_action_serve', args=(signature, self.image.id, 'fill-800x600'))) 350 351 self.assertEqual(response.status_code, 200) 352 self.assertTrue(response.streaming) 353 self.assertEqual(response['Content-Type'], 'image/png') 354 355 def test_get_with_redirect_action(self): 356 signature = generate_signature(self.image.id, 'fill-800x600') 357 response = self.client.get(reverse('wagtailimages_serve_action_redirect', args=(signature, self.image.id, 'fill-800x600'))) 358 359 expected_redirect_url = '/media/images/{filename[0]}.2e16d0ba.fill-800x600{filename[1]}'.format( 360 filename=os.path.splitext(os.path.basename(self.image.file.path)) 361 ) 362 363 self.assertRedirects(response, expected_redirect_url, status_code=301, fetch_redirect_response=False) 364 365 def test_init_with_unknown_action_raises_error(self): 366 with self.assertRaises(ImproperlyConfigured): 367 ServeView.as_view(action='unknown') 368 369 def test_get_with_custom_key(self): 370 """ 371 Test that that the key can be changed on the view 372 """ 373 # Generate signature 374 signature = generate_signature(self.image.id, 'fill-800x600', key='custom') 375 376 # Get the image 377 response = self.client.get(reverse('wagtailimages_serve_custom_key', args=(signature, self.image.id, 'fill-800x600')) + 'test.png') 378 379 # Check response 380 self.assertEqual(response.status_code, 200) 381 382 def test_get_with_custom_key_using_default_key(self): 383 """ 384 Test that that the key can be changed on the view 385 386 This tests that the default key no longer works when the key is changed on the view 387 """ 388 # Generate signature 389 signature = generate_signature(self.image.id, 'fill-800x600') 390 391 # Get the image 392 response = self.client.get(reverse('wagtailimages_serve_custom_key', args=(signature, self.image.id, 'fill-800x600')) + 'test.png') 393 394 # Check response 395 self.assertEqual(response.status_code, 403) 396 397 def test_get_invalid_signature(self): 398 """ 399 Test that an invalid signature returns a 403 response 400 """ 401 # Generate a signature for the incorrect image id 402 signature = generate_signature(self.image.id + 1, 'fill-800x600') 403 404 # Get the image 405 response = self.client.get(reverse('wagtailimages_serve', args=(signature, self.image.id, 'fill-800x600'))) 406 407 # Check response 408 self.assertEqual(response.status_code, 403) 409 410 def test_get_invalid_filter_spec(self): 411 """ 412 Test that an invalid filter spec returns a 400 response 413 414 This is very unlikely to happen in reality. A user would have 415 to create signature for the invalid filter spec which can't be 416 done with Wagtails built in URL generator. We should test it 417 anyway though. 418 """ 419 # Generate a signature with the invalid filterspec 420 signature = generate_signature(self.image.id, 'bad-filter-spec') 421 422 # Get the image 423 response = self.client.get(reverse('wagtailimages_serve', args=(signature, self.image.id, 'bad-filter-spec'))) 424 425 # Check response 426 self.assertEqual(response.status_code, 400) 427 428 def test_get_missing_source_image_file(self): 429 """ 430 Test that a missing image file gives a 410 response 431 432 When the source image file is missing, it is presumed deleted so we 433 return a 410 "Gone" response. 434 """ 435 # Delete the image file 436 os.remove(self.image.file.path) 437 438 # Get the image 439 signature = generate_signature(self.image.id, 'fill-800x600') 440 response = self.client.get(reverse('wagtailimages_serve', args=(signature, self.image.id, 'fill-800x600'))) 441 442 # Check response 443 self.assertEqual(response.status_code, 410) 444 445 446class TestFrontendSendfileView(TestCase): 447 448 def setUp(self): 449 self.image = Image.objects.create( 450 title="Test image", 451 file=get_test_image_file(), 452 ) 453 454 @override_settings(SENDFILE_BACKEND='sendfile.backends.development') 455 @unittest.skipIf(not sendfile_mod, 'Missing django-sendfile app.') 456 def test_sendfile_nobackend(self): 457 signature = generate_signature(self.image.id, 'fill-800x600') 458 response = self.client.get(reverse('wagtailimages_sendfile', 459 args=(signature, self.image.id, 460 'fill-800x600'))) 461 462 self.assertEqual(response.status_code, 200) 463 self.assertEqual(response['Content-Type'], 'image/png') 464 465 @override_settings(SENDFILE_BACKEND='sendfile.backends.development') 466 def test_sendfile_dummy_backend(self): 467 signature = generate_signature(self.image.id, 'fill-800x600') 468 response = self.client.get(reverse('wagtailimages_sendfile_dummy', 469 args=(signature, self.image.id, 470 'fill-800x600'))) 471 472 self.assertEqual(response.status_code, 200) 473 self.assertTrue(response.content, 'Dummy backend response') 474 475 476class TestRect(TestCase): 477 def test_init(self): 478 rect = Rect(100, 150, 200, 250) 479 self.assertEqual(rect.left, 100) 480 self.assertEqual(rect.top, 150) 481 self.assertEqual(rect.right, 200) 482 self.assertEqual(rect.bottom, 250) 483 484 def test_equality(self): 485 self.assertEqual(Rect(100, 150, 200, 250), Rect(100, 150, 200, 250)) 486 self.assertNotEqual(Rect(100, 150, 200, 250), Rect(10, 15, 20, 25)) 487 488 def test_getitem(self): 489 rect = Rect(100, 150, 200, 250) 490 self.assertEqual(rect[0], 100) 491 self.assertEqual(rect[1], 150) 492 self.assertEqual(rect[2], 200) 493 self.assertEqual(rect[3], 250) 494 self.assertRaises(IndexError, rect.__getitem__, 4) 495 496 def test_as_tuple(self): 497 rect = Rect(100, 150, 200, 250) 498 self.assertEqual(rect.as_tuple(), (100, 150, 200, 250)) 499 500 def test_size(self): 501 rect = Rect(100, 150, 200, 350) 502 self.assertIsInstance(rect.size, Vector) 503 self.assertEqual(rect.size, (100, 200)) 504 self.assertEqual(rect.width, 100) 505 self.assertEqual(rect.height, 200) 506 507 def test_set_size_with_tuple(self): 508 rect = Rect(100, 150, 200, 350) 509 rect.size = (200, 400) 510 self.assertEqual(rect, (50, 50, 250, 450)) 511 512 def test_set_size_with_vector(self): 513 rect = Rect(100, 150, 200, 350) 514 rect.size = Vector(200, 400) 515 self.assertEqual(rect, (50, 50, 250, 450)) 516 517 def test_centroid(self): 518 rect = Rect(100, 150, 200, 350) 519 self.assertIsInstance(rect.centroid, Vector) 520 self.assertEqual(rect.centroid, (150, 250)) 521 self.assertEqual(rect.x, 150) 522 self.assertEqual(rect.y, 250) 523 self.assertEqual(rect.centroid_x, 150) 524 self.assertEqual(rect.centroid_y, 250) 525 526 def test_set_centroid_with_tuple(self): 527 rect = Rect(100, 150, 200, 350) 528 rect.centroid = (500, 500) 529 self.assertEqual(rect, (450, 400, 550, 600)) 530 531 def test_set_centroid_with_vector(self): 532 rect = Rect(100, 150, 200, 350) 533 rect.centroid = Vector(500, 500) 534 self.assertEqual(rect, (450, 400, 550, 600)) 535 536 def test_repr(self): 537 rect = Rect(100, 150, 200, 250) 538 self.assertEqual(repr(rect), "Rect(left: 100, top: 150, right: 200, bottom: 250)") 539 540 def test_from_point(self): 541 rect = Rect.from_point(100, 200, 50, 20) 542 self.assertEqual(rect, Rect(75, 190, 125, 210)) 543 544 545class TestGetImageForm(TestCase, WagtailTestUtils): 546 def test_fields(self): 547 form = get_image_form(Image) 548 549 self.assertEqual(list(form.base_fields.keys()), [ 550 'title', 551 'file', 552 'collection', 553 'tags', 554 'focal_point_x', 555 'focal_point_y', 556 'focal_point_width', 557 'focal_point_height', 558 ]) 559 560 def test_admin_form_fields_attribute(self): 561 form = get_image_form(CustomImage) 562 563 self.assertEqual(list(form.base_fields.keys()), [ 564 'title', 565 'file', 566 'collection', 567 'tags', 568 'focal_point_x', 569 'focal_point_y', 570 'focal_point_width', 571 'focal_point_height', 572 'caption', 573 'fancy_caption', 574 ]) 575 576 def test_file_field(self): 577 form = get_image_form(WagtailImage) 578 579 self.assertIsInstance(form.base_fields['file'], WagtailImageField) 580 self.assertIsInstance(form.base_fields['file'].widget, forms.FileInput) 581 582 def test_tags_field(self): 583 form = get_image_form(WagtailImage) 584 585 self.assertIsInstance(form.base_fields['tags'], TagField) 586 self.assertIsInstance(form.base_fields['tags'].widget, TagWidget) 587 588 def test_focal_point_fields(self): 589 form = get_image_form(WagtailImage) 590 591 self.assertIsInstance(form.base_fields['focal_point_x'], forms.IntegerField) 592 self.assertIsInstance(form.base_fields['focal_point_y'], forms.IntegerField) 593 self.assertIsInstance(form.base_fields['focal_point_width'], forms.IntegerField) 594 self.assertIsInstance(form.base_fields['focal_point_height'], forms.IntegerField) 595 596 self.assertIsInstance(form.base_fields['focal_point_x'].widget, forms.HiddenInput) 597 self.assertIsInstance(form.base_fields['focal_point_y'].widget, forms.HiddenInput) 598 self.assertIsInstance(form.base_fields['focal_point_width'].widget, forms.HiddenInput) 599 self.assertIsInstance(form.base_fields['focal_point_height'].widget, forms.HiddenInput) 600 601 602class TestRenditionFilenames(TestCase): 603 # Can't create image in setUp as we need a unique filename for each test. 604 # This stops Django appending some rubbish to the filename which makes 605 # the assertions difficult. 606 607 def test_normal_filter(self): 608 image = Image.objects.create( 609 title="Test image", 610 file=get_test_image_file(filename='test_rf1.png'), 611 ) 612 rendition = image.get_rendition('width-100') 613 614 self.assertEqual(rendition.file.name, 'images/test_rf1.width-100.png') 615 616 def test_fill_filter(self): 617 image = Image.objects.create( 618 title="Test image", 619 file=get_test_image_file(filename='test_rf2.png'), 620 ) 621 rendition = image.get_rendition('fill-100x100') 622 623 self.assertEqual(rendition.file.name, 'images/test_rf2.2e16d0ba.fill-100x100.png') 624 625 def test_fill_filter_with_focal_point(self): 626 image = Image.objects.create( 627 title="Test image", 628 file=get_test_image_file(filename='test_rf3.png'), 629 ) 630 image.set_focal_point(Rect(100, 100, 200, 200)) 631 image.save() 632 633 rendition = image.get_rendition('fill-100x100') 634 635 self.assertEqual(rendition.file.name, 'images/test_rf3.15ee4958.fill-100x100.png') 636 637 def test_filter_with_pipe_gets_dotted(self): 638 image = Image.objects.create( 639 title="Test image", 640 file=get_test_image_file(filename='test_rf4.png'), 641 ) 642 image.set_focal_point(Rect(100, 100, 200, 200)) 643 image.save() 644 645 rendition = image.get_rendition('fill-200x200|height-150') 646 647 self.assertEqual(rendition.file.name, 'images/test_rf4.15ee4958.fill-200x200.height-150.png') 648 649 650class TestDifferentUpload(TestCase): 651 def test_upload_path(self): 652 image = CustomImageFilePath.objects.create( 653 title="Test image", 654 file=get_test_image_file(), 655 ) 656 657 second_image = CustomImageFilePath.objects.create( 658 title="Test Image", 659 file=get_test_image_file(colour='black'), 660 661 ) 662 663 # The files should be uploaded based on it's content, not just 664 # it's filename 665 self.assertFalse(image.file.url == second_image.file.url) 666 667 668class TestGetImageModel(WagtailTestUtils, TestCase): 669 @override_settings(WAGTAILIMAGES_IMAGE_MODEL='tests.CustomImage') 670 def test_custom_get_image_model(self): 671 """Test get_image_model with a custom image model""" 672 self.assertIs(get_image_model(), CustomImage) 673 674 @override_settings(WAGTAILIMAGES_IMAGE_MODEL='tests.CustomImage') 675 def test_custom_get_image_model_string(self): 676 """Test get_image_model_string with a custom image model""" 677 self.assertEqual(get_image_model_string(), 'tests.CustomImage') 678 679 @override_settings() 680 def test_standard_get_image_model(self): 681 """Test get_image_model with no WAGTAILIMAGES_IMAGE_MODEL""" 682 del settings.WAGTAILIMAGES_IMAGE_MODEL 683 from wagtail.images.models import Image 684 self.assertIs(get_image_model(), Image) 685 686 @override_settings() 687 def test_standard_get_image_model_string(self): 688 """Test get_image_model_STRING with no WAGTAILIMAGES_IMAGE_MODEL""" 689 del settings.WAGTAILIMAGES_IMAGE_MODEL 690 self.assertEqual(get_image_model_string(), 'wagtailimages.Image') 691 692 @override_settings(WAGTAILIMAGES_IMAGE_MODEL='tests.UnknownModel') 693 def test_unknown_get_image_model(self): 694 """Test get_image_model with an unknown model""" 695 with self.assertRaises(ImproperlyConfigured): 696 get_image_model() 697 698 @override_settings(WAGTAILIMAGES_IMAGE_MODEL='invalid-string') 699 def test_invalid_get_image_model(self): 700 """Test get_image_model with an invalid model string""" 701 with self.assertRaises(ImproperlyConfigured): 702 get_image_model() 703