class ImageScalingTests(unittest.TestCase): layer = PLONE_NAMEDFILE_INTEGRATION_TESTING def setUp(self): data = getFile('image.gif').read() item = DummyContent() item.image = NamedImage(data, 'image/gif', u'image.gif') self.layer['app']._setOb('item', item) self.item = self.layer['app'].item self.scaling = ImageScaling(self.item, None) def testCreateScale(self): foo = self.scaling.scale('image', width=100, height=80) self.assertTrue(foo.uid) self.assertEqual(foo.mimetype, 'image/jpeg') self.assertEqual(foo.width, 80) self.assertEqual(foo.height, 80) assertImage(self, foo.data.data, 'JPEG', (80, 80)) def testCreateScaleWithoutData(self): item = DummyContent() scaling = ImageScaling(item, None) foo = scaling.scale('image', width=100, height=80) self.assertEqual(foo, None) def testGetScaleByName(self): self.scaling.available_sizes = {'foo': (60, 60)} foo = self.scaling.scale('image', scale='foo') self.assertTrue(foo.uid) self.assertEqual(foo.mimetype, 'image/jpeg') self.assertEqual(foo.width, 60) self.assertEqual(foo.height, 60) assertImage(self, foo.data.data, 'JPEG', (60, 60)) expected_url = re.compile( r'http://nohost/item/@@images/[-a-z0-9]{36}\.jpeg') self.assertTrue(expected_url.match(foo.absolute_url())) self.assertEqual(foo.url, foo.absolute_url()) tag = foo.tag() base = IAbsoluteURL(self.item, '') expected = ( r'<img src="{0:s}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />'.format( base)) groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetUnknownScale(self): foo = self.scaling.scale('image', scale='foo?') self.assertEqual(foo, None) def testScaleInvalidation(self): # first get the scale of the original image self.scaling.available_sizes = {'foo': (23, 23)} foo1 = self.scaling.scale('image', scale='foo') wait_to_ensure_modified() # now upload a new one and make sure the scale has changed data = getFile('image.jpg').read() self.item.image = NamedImage(data, 'image/jpeg', u'image.jpg') foo2 = self.scaling.scale('image', scale='foo') self.assertFalse(foo1.data == foo2.data, 'scale not updated?') def testCustomSizeChange(self): # set custom image sizes & view a scale self.scaling.available_sizes = {'foo': (23, 23)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 23) self.assertEqual(foo.height, 23) # now let's update the scale dimensions, after which the scale # shouldn't be the same... self.scaling.available_sizes = {'foo': (42, 42)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 42) self.assertEqual(foo.height, 42) def testAvailableSizes(self): # by default, no named scales are configured self.assertEqual(self.scaling.available_sizes, {}) # a callable can be used to look up the available sizes def custom_available_sizes(): return {'bar': (10, 10)} sm = getSiteManager() sm.registerUtility(component=custom_available_sizes, provided=IAvailableSizes) self.assertEqual(self.scaling.available_sizes, {'bar': (10, 10)}) sm.unregisterUtility(provided=IAvailableSizes) # for testing purposes, the sizes may also be set directly on # the scaling adapter self.scaling.available_sizes = {'qux': (12, 12)} self.assertEqual(self.scaling.available_sizes, {'qux': (12, 12)}) def testGetAvailableSizes(self): self.scaling.available_sizes = {'foo': (60, 60)} assert self.scaling.getAvailableSizes('image') == {'foo': (60, 60)} def testGetImageSize(self): assert self.scaling.getImageSize('image') == (200, 200) def testGetOriginalScaleTag(self): tag = self.scaling.tag('image') base = IAbsoluteURL(self.item, '') expected = ( r'<img src="{0:s}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />'.format( base)) self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithNonASCIITitle(self): self.item.title = '\xc3\xbc' tag = self.scaling.tag('image') base = IAbsoluteURL(self.item, '') expected = ( r'<img src="{0:s}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />'.format( base)) self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithUnicodeTitle(self): self.item.Title = lambda: b'\xc3\xbc'.decode('utf8') tag = self.scaling.tag('image') base = IAbsoluteURL(self.item, '') expected = ( r'<img src="{0:s}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />'.format( base)) self.assertTrue(re.match(expected, tag).groups()) def testScaledImageQuality(self): # scale an image, record its size foo = self.scaling.scale('image', width=100, height=80) size_foo = foo.data.getSize() # let's pretend p.a.imaging set the scaling quality to "really sloppy" gsm = getGlobalSiteManager() qualitySupplier = DummyQualitySupplier() gsm.registerUtility(qualitySupplier.getQuality, IScaledImageQuality) wait_to_ensure_modified() # now scale again bar = self.scaling.scale('image', width=100, height=80) size_bar = bar.data.getSize() # first one should be bigger self.assertTrue(size_foo > size_bar)
class ImageScalingTests(NamedFileTestCase): def afterSetUp(self): data = getFile('image.gif').read() item = DummyContent() item.image = NamedImage(data, 'image/gif', u'image.gif') self.app._setOb('item', item) self.item = self.app.item self.scaling = ImageScaling(self.app.item, None) def testCreateScale(self): foo = self.scaling.scale('image', width=100, height=80) self.failUnless(foo.uid) self.assertEqual(foo.mimetype, 'image/jpeg') self.assertEqual(foo.width, 80) self.assertEqual(foo.height, 80) self.assertImage(foo.data.data, 'JPEG', (80, 80)) def testCreateScaleWithoutData(self): item = DummyContent() scaling = ImageScaling(item, None) foo = scaling.scale('image', width=100, height=80) self.assertEqual(foo, None) def testGetScaleByName(self): self.scaling.available_sizes = {'foo': (60,60)} foo = self.scaling.scale('image', scale='foo') self.failUnless(foo.uid) self.assertEqual(foo.mimetype, 'image/jpeg') self.assertEqual(foo.width, 60) self.assertEqual(foo.height, 60) self.assertImage(foo.data.data, 'JPEG', (60, 60)) expected_url = re.compile(r'http://nohost/item/@@images/[-a-z0-9]{36}\.jpeg') self.failUnless(expected_url.match(foo.absolute_url())) self.assertEqual(foo.url, foo.absolute_url()) tag = foo.tag() base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />' % base groups = re.match(expected, tag).groups() self.failUnless(groups, tag) def testGetUnknownScale(self): foo = self.scaling.scale('image', scale='foo?') self.assertEqual(foo, None) def testScaleInvalidation(self): # first get the scale of the original image self.scaling.available_sizes = {'foo': (23,23)} foo1 = self.scaling.scale('image', scale='foo') # now upload a new one and make sure the scale has changed data = getFile('image.jpg').read() self.item.image = NamedImage(data, 'image/jpeg', u'image.jpg') foo2 = self.scaling.scale('image', scale='foo') self.failIf(foo1.data == foo2.data, 'scale not updated?') def testCustomSizeChange(self): # set custom image sizes & view a scale self.scaling.available_sizes = {'foo': (23,23)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 23) self.assertEqual(foo.height, 23) # now let's update the scale dimensions, after which the scale # shouldn't be the same... self.scaling.available_sizes = {'foo': (42,42)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 42) self.assertEqual(foo.height, 42) def testAvailableSizes(self): # by default, no named scales are configured self.assertEqual(self.scaling.available_sizes, {}) # a callable can be used to look up the available sizes def custom_available_sizes(): return {'bar': (10,10)} sm = getSiteManager() sm.registerUtility(component=custom_available_sizes, provided=IAvailableSizes) self.assertEqual(self.scaling.available_sizes, {'bar': (10,10)}) sm.unregisterUtility(provided=IAvailableSizes) # for testing purposes, the sizes may also be set directly on # the scaling adapter self.scaling.available_sizes = {'qux': (12, 12)} self.assertEqual(self.scaling.available_sizes, {'qux': (12, 12)}) def testGuardedAccess(self): # make sure it's not possible to access scales of forbidden images self.item.__allow_access_to_unprotected_subobjects__ = 0 self.assertRaises(Unauthorized, self.scaling.guarded_orig_image, 'image') self.item.__allow_access_to_unprotected_subobjects__ = 1 def testGetAvailableSizes(self): self.scaling.available_sizes = {'foo': (60,60)} assert self.scaling.getAvailableSizes('image') == {'foo': (60, 60)} def testGetImageSize(self): assert self.scaling.getImageSize('image') == (200, 200) def testGetOriginalScaleTag(self): tag = self.scaling.tag('image') base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />' % base self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithNonASCIITitle(self): self.item.title = '\xc3\xbc' tag = self.scaling.tag('image') base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />' % base self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithUnicodeTitle(self): self.item.title = u'Unicode here' tag = self.scaling.tag('image') base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="Unicode here" title="Unicode here" height="(\d+)" width="(\d+)" />' % base self.assertTrue(re.match(expected, tag).groups())
class ImageScalingTests(NamedFileTestCase): def afterSetUp(self): data = getFile('image.gif').read() item = DummyContent() item.image = NamedImage(data, 'image/gif', u'image.gif') self.app._setOb('item', item) self.item = self.app.item self.scaling = ImageScaling(self.app.item, None) def testCreateScale(self): foo = self.scaling.scale('image', width=100, height=80) self.failUnless(foo.uid) self.assertEqual(foo.mimetype, 'image/jpeg') self.assertEqual(foo.width, 80) self.assertEqual(foo.height, 80) self.assertImage(foo.data.data, 'JPEG', (80, 80)) def testCreateScaleWithoutData(self): item = DummyContent() scaling = ImageScaling(item, None) foo = scaling.scale('image', width=100, height=80) self.assertEqual(foo, None) def testGetScaleByName(self): self.scaling.available_sizes = {'foo': (60, 60)} foo = self.scaling.scale('image', scale='foo') self.failUnless(foo.uid) self.assertEqual(foo.mimetype, 'image/jpeg') self.assertEqual(foo.width, 60) self.assertEqual(foo.height, 60) self.assertImage(foo.data.data, 'JPEG', (60, 60)) expected_url = re.compile( r'http://nohost/item/@@images/[-a-z0-9]{36}\.jpeg') self.failUnless(expected_url.match(foo.absolute_url())) self.assertEqual(foo.url, foo.absolute_url()) tag = foo.tag() base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />' % base groups = re.match(expected, tag).groups() self.failUnless(groups, tag) def testGetUnknownScale(self): foo = self.scaling.scale('image', scale='foo?') self.assertEqual(foo, None) def testScaleInvalidation(self): # first get the scale of the original image self.scaling.available_sizes = {'foo': (23, 23)} foo1 = self.scaling.scale('image', scale='foo') # now upload a new one and make sure the scale has changed data = getFile('image.jpg').read() self.item.image = NamedImage(data, 'image/jpeg', u'image.jpg') foo2 = self.scaling.scale('image', scale='foo') self.failIf(foo1.data == foo2.data, 'scale not updated?') def testCustomSizeChange(self): # set custom image sizes & view a scale self.scaling.available_sizes = {'foo': (23, 23)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 23) self.assertEqual(foo.height, 23) # now let's update the scale dimensions, after which the scale # shouldn't be the same... self.scaling.available_sizes = {'foo': (42, 42)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 42) self.assertEqual(foo.height, 42) def testAvailableSizes(self): # by default, no named scales are configured self.assertEqual(self.scaling.available_sizes, {}) # a callable can be used to look up the available sizes def custom_available_sizes(): return {'bar': (10, 10)} sm = getSiteManager() sm.registerUtility(component=custom_available_sizes, provided=IAvailableSizes) self.assertEqual(self.scaling.available_sizes, {'bar': (10, 10)}) sm.unregisterUtility(provided=IAvailableSizes) # for testing purposes, the sizes may also be set directly on # the scaling adapter self.scaling.available_sizes = {'qux': (12, 12)} self.assertEqual(self.scaling.available_sizes, {'qux': (12, 12)}) def testGuardedAccess(self): # make sure it's not possible to access scales of forbidden images self.item.__allow_access_to_unprotected_subobjects__ = 0 self.assertRaises(Unauthorized, self.scaling.guarded_orig_image, 'image') self.item.__allow_access_to_unprotected_subobjects__ = 1 def testGetAvailableSizes(self): self.scaling.available_sizes = {'foo': (60, 60)} assert self.scaling.getAvailableSizes('image') == {'foo': (60, 60)} def testGetImageSize(self): assert self.scaling.getImageSize('image') == (200, 200) def testGetOriginalScaleTag(self): tag = self.scaling.tag('image') base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />' % base self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithNonASCIITitle(self): self.item.title = '\xc3\xbc' tag = self.scaling.tag('image') base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />' % base self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithUnicodeTitle(self): self.item.Title = lambda: '\xc3\xbc'.decode('utf8') tag = self.scaling.tag('image') base = self.item.absolute_url() expected = r'<img src="%s/@@images/([-0-9a-f]{36}).(jpeg|gif|png)" ' \ r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />' % base self.assertTrue(re.match(expected, tag).groups()) def testScaledImageQuality(self): # scale an image, record its size foo = self.scaling.scale('image', width=100, height=80) size_foo = foo.data.getSize() # let's pretend p.a.imaging set the scaling quality to "really sloppy" gsm = getGlobalSiteManager() qualitySupplier = DummyQualitySupplier() gsm.registerUtility(qualitySupplier.getQuality, IScaledImageQuality) # now scale again bar = self.scaling.scale('image', width=100, height=80) size_bar = bar.data.getSize() # first one should be bigger self.assertGreater(size_foo, size_bar)
class ImageScalingTests(unittest.TestCase): layer = PLONE_NAMEDFILE_INTEGRATION_TESTING def setUp(self): data = getFile('image.png').read() item = DummyContent() item.image = NamedImage(data, 'image/png', u'image.png') self.layer['app']._setOb('item', item) self.item = self.layer['app'].item self.scaling = ImageScaling(self.item, None) def testCreateScale(self): foo = self.scaling.scale('image', width=100, height=80) self.assertTrue(foo.uid) self.assertEqual(foo.mimetype, 'image/png') self.assertIsInstance(foo.mimetype, str) self.assertEqual(foo.data.contentType, 'image/png') self.assertIsInstance(foo.data.contentType, str) self.assertEqual(foo.width, 80) self.assertEqual(foo.height, 80) assertImage(self, foo.data.data, 'PNG', (80, 80)) def testCreateHighPixelDensityScale(self): self.scaling.getHighPixelDensityScales = lambda: [{ 'scale': 2, 'quality': 66 }] foo = self.scaling.scale('image', width=100, height=80) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['height'], 160) self.assertEqual(foo.srcset[0]['width'], 160) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (160, 160)) def testCreateScaleWithoutData(self): item = DummyContent() scaling = ImageScaling(item, None) foo = scaling.scale('image', width=100, height=80) self.assertEqual(foo, None) def testCreateHighPixelDensityScaleWithoutData(self): item = DummyContent() scaling = ImageScaling(item, None) scaling.getHighPixelDensityScales = lambda: [{ 'scale': 2, 'quality': 66 }] foo = scaling.scale('image', width=100, height=80) self.assertFalse(hasattr(foo, 'srcset')) def testGetScaleByName(self): self.scaling.available_sizes = {'foo': (60, 60)} foo = self.scaling.scale('image', scale='foo') self.assertTrue(foo.uid) self.assertEqual(foo.mimetype, 'image/png') self.assertIsInstance(foo.mimetype, str) self.assertEqual(foo.data.contentType, 'image/png') self.assertIsInstance(foo.data.contentType, str) self.assertEqual(foo.width, 60) self.assertEqual(foo.height, 60) assertImage(self, foo.data.data, 'PNG', (60, 60)) expected_url = re.compile( r'http://nohost/item/@@images/[-a-z0-9]{36}\.png') self.assertTrue(expected_url.match(foo.absolute_url())) self.assertEqual(foo.url, foo.absolute_url()) tag = foo.tag() base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />'.format( base, ) groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetHighPixelDensityScaleByName(self): self.scaling.getHighPixelDensityScales = lambda: [{ 'scale': 2, 'quality': 66 }] self.scaling.available_sizes = {'foo': (60, 60)} foo = self.scaling.scale('image', scale='foo') self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = (r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetHPDScaleByWidthAndHeight(self): self.scaling.getHighPixelDensityScales = lambda: [{ 'scale': 2, 'quality': 66 }] foo = self.scaling.scale('image', width=60, height=60) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = (r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetHPDScaleByWidthOnly(self): self.scaling.getHighPixelDensityScales = lambda: [{ 'scale': 2, 'quality': 66 }] foo = self.scaling.scale('image', width=60) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = (r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetHPDScaleByHeightOnly(self): self.scaling.getHighPixelDensityScales = lambda: [{ 'scale': 2, 'quality': 66 }] foo = self.scaling.scale('image', height=60) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = (r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetUnknownScale(self): foo = self.scaling.scale('image', scale='foo?') self.assertEqual(foo, None) def testScaleInvalidation(self): # first get the scale of the original image self.scaling.available_sizes = {'foo': (23, 23)} foo1 = self.scaling.scale('image', scale='foo') wait_to_ensure_modified() # now upload a new one and make sure the scale has changed data = getFile('image.jpg').read() self.item.image = NamedImage(data, 'image/jpeg', u'image.jpg') foo2 = self.scaling.scale('image', scale='foo') self.assertFalse(foo1.data == foo2.data, 'scale not updated?') def testCustomSizeChange(self): # set custom image sizes & view a scale self.scaling.available_sizes = {'foo': (23, 23)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 23) self.assertEqual(foo.height, 23) # now let's update the scale dimensions, after which the scale # shouldn't be the same... self.scaling.available_sizes = {'foo': (42, 42)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 42) self.assertEqual(foo.height, 42) def testAvailableSizes(self): # by default, no named scales are configured self.assertEqual(self.scaling.available_sizes, {}) # a callable can be used to look up the available sizes def custom_available_sizes(): return {'bar': (10, 10)} sm = getSiteManager() sm.registerUtility(component=custom_available_sizes, provided=IAvailableSizes) self.assertEqual(self.scaling.available_sizes, {'bar': (10, 10)}) sm.unregisterUtility(provided=IAvailableSizes) # for testing purposes, the sizes may also be set directly on # the scaling adapter self.scaling.available_sizes = {'qux': (12, 12)} self.assertEqual(self.scaling.available_sizes, {'qux': (12, 12)}) def testGuardedAccess(self): # make sure it's not possible to access scales of forbidden images self.item.__allow_access_to_unprotected_subobjects__ = 0 self.assertRaises(Unauthorized, self.scaling.guarded_orig_image, 'image') self.item.__allow_access_to_unprotected_subobjects__ = 1 def testGetAvailableSizes(self): self.scaling.available_sizes = {'foo': (60, 60)} assert self.scaling.getAvailableSizes('image') == {'foo': (60, 60)} def testGetImageSize(self): assert self.scaling.getImageSize('image') == (200, 200) def testGetOriginalScaleTag(self): tag = self.scaling.tag('image') base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />'.format( base, ) self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithNonASCIITitle(self): self.item.title = '\xc3\xbc' tag = self.scaling.tag('image') base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />'.format( base, ) self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithUnicodeTitle(self): self.item.Title = lambda: '\xc3\xbc'.decode('utf8') tag = self.scaling.tag('image') base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />'.format( base, ) self.assertTrue(re.match(expected, tag).groups()) def testScaledJpegImageQuality(self): """Test image quality setting for jpeg images. Image quality not available for PNG images. """ data = getFile('image.jpg').read() item = DummyContent() item.image = NamedImage(data, 'image/png', u'image.jpg') scaling = ImageScaling(item, None) # scale an image, record its size foo = scaling.scale('image', width=100, height=80) size_foo = foo.data.getSize() # let's pretend p.a.imaging set the scaling quality to "really sloppy" gsm = getGlobalSiteManager() qualitySupplier = DummyQualitySupplier() gsm.registerUtility(qualitySupplier.getQuality, IScaledImageQuality) wait_to_ensure_modified() # now scale again bar = scaling.scale('image', width=100, height=80) size_bar = bar.data.getSize() # first one should be bigger self.assertTrue(size_foo > size_bar) def testOversizedHighPixelDensityScale(self): orig_size = max(self.scaling.getImageSize('image')) scale_size = orig_size / 2 self.scaling.getHighPixelDensityScales = lambda: [{ 'scale': 2, 'quality': 66 }, { 'scale': 3, 'quality': 66 }] foo = self.scaling.scale('image', width=scale_size, height=scale_size) self.assertEqual(len(foo.srcset), 1) self.assertEqual(foo.srcset[0]['scale'], 2)
class ImageScalingTests(unittest.TestCase): layer = PLONE_NAMEDFILE_INTEGRATION_TESTING def setUp(self): data = getFile('image.png') item = DummyContent() item.image = NamedImage(data, 'image/png', u'image.png') self.layer['app']._setOb('item', item) self.item = self.layer['app'].item self.scaling = ImageScaling(self.item, None) def testCreateScale(self): foo = self.scaling.scale('image', width=100, height=80) self.assertTrue(foo.uid) self.assertEqual(foo.mimetype, 'image/png') self.assertIsInstance(foo.mimetype, str) self.assertEqual(foo.data.contentType, 'image/png') self.assertIsInstance(foo.data.contentType, str) self.assertEqual(foo.width, 80) self.assertEqual(foo.height, 80) assertImage(self, foo.data.data, 'PNG', (80, 80)) def testCreateHighPixelDensityScale(self): self.scaling.getHighPixelDensityScales = lambda: [{'scale': 2, 'quality': 66}] foo = self.scaling.scale('image', width=100, height=80) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['height'], 160) self.assertEqual(foo.srcset[0]['width'], 160) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (160, 160)) def testCreateScaleWithoutData(self): item = DummyContent() scaling = ImageScaling(item, None) foo = scaling.scale('image', width=100, height=80) self.assertEqual(foo, None) def testCreateHighPixelDensityScaleWithoutData(self): item = DummyContent() scaling = ImageScaling(item, None) scaling.getHighPixelDensityScales = lambda: [{'scale': 2, 'quality': 66}] foo = scaling.scale('image', width=100, height=80) self.assertFalse(hasattr(foo, 'srcset')) def testGetScaleByName(self): self.scaling.available_sizes = {'foo': (60, 60)} foo = self.scaling.scale('image', scale='foo') self.assertTrue(foo.uid) self.assertEqual(foo.mimetype, 'image/png') self.assertIsInstance(foo.mimetype, str) self.assertEqual(foo.data.contentType, 'image/png') self.assertIsInstance(foo.data.contentType, str) self.assertEqual(foo.width, 60) self.assertEqual(foo.height, 60) assertImage(self, foo.data.data, 'PNG', (60, 60)) expected_url = re.compile( r'http://nohost/item/@@images/[-a-z0-9]{36}\.png') self.assertTrue(expected_url.match(foo.absolute_url())) self.assertEqual(foo.url, foo.absolute_url()) tag = foo.tag() base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />'.format( base, ) groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetHighPixelDensityScaleByName(self): self.scaling.getHighPixelDensityScales = lambda: [{'scale': 2, 'quality': 66}] self.scaling.available_sizes = {'foo': (60, 60)} foo = self.scaling.scale('image', scale='foo') self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = ( r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetRetinaScaleByWidthAndHeight(self): self.scaling.getHighPixelDensityScales = lambda: [{'scale': 2, 'quality': 66}] foo = self.scaling.scale('image', width=60, height=60) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = ( r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetRetinaScaleByWidthOnly(self): self.scaling.getHighPixelDensityScales = lambda: [{'scale': 2, 'quality': 66}] foo = self.scaling.scale('image', width=60) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = ( r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetRetinaScaleByHeightOnly(self): self.scaling.getHighPixelDensityScales = lambda: [{'scale': 2, 'quality': 66}] foo = self.scaling.scale('image', height=60) self.assertTrue(foo.srcset) self.assertEqual(foo.srcset[0]['mimetype'], 'image/png') self.assertEqual(foo.srcset[0]['width'], 120) self.assertEqual(foo.srcset[0]['height'], 120) assertImage(self, foo.srcset[0]['data'].data, 'PNG', (120, 120)) tag = foo.tag() base = self.item.absolute_url() expected = ( r'<img src="{0}'.format(base) + r'/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)" ' r'alt="foo" title="foo" height="(\d+)" width="(\d+)" ' r'srcset="http://nohost/item/@@images/([-0-9a-f]{36})' r'.(jpeg|gif|png)' r' 2x" />') groups = re.match(expected, tag).groups() self.assertTrue(groups, tag) def testGetUnknownScale(self): foo = self.scaling.scale('image', scale='foo?') self.assertEqual(foo, None) def testScaleInvalidation(self): # first get the scale of the original image self.scaling.available_sizes = {'foo': (23, 23)} foo1 = self.scaling.scale('image', scale='foo') wait_to_ensure_modified() # now upload a new one and make sure the scale has changed data = getFile('image.jpg') self.item.image = NamedImage(data, 'image/jpeg', u'image.jpg') foo2 = self.scaling.scale('image', scale='foo') self.assertFalse(foo1.data == foo2.data, 'scale not updated?') def testCustomSizeChange(self): # set custom image sizes & view a scale self.scaling.available_sizes = {'foo': (23, 23)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 23) self.assertEqual(foo.height, 23) # now let's update the scale dimensions, after which the scale # shouldn't be the same... self.scaling.available_sizes = {'foo': (42, 42)} foo = self.scaling.scale('image', scale='foo') self.assertEqual(foo.width, 42) self.assertEqual(foo.height, 42) def testAvailableSizes(self): # by default, no named scales are configured self.assertEqual(self.scaling.available_sizes, {}) # a callable can be used to look up the available sizes def custom_available_sizes(): return {'bar': (10, 10)} sm = getSiteManager() sm.registerUtility(component=custom_available_sizes, provided=IAvailableSizes) self.assertEqual(self.scaling.available_sizes, {'bar': (10, 10)}) sm.unregisterUtility(provided=IAvailableSizes) # for testing purposes, the sizes may also be set directly on # the scaling adapter self.scaling.available_sizes = {'qux': (12, 12)} self.assertEqual(self.scaling.available_sizes, {'qux': (12, 12)}) def testGuardedAccess(self): # make sure it's not possible to access scales of forbidden images self.item.__allow_access_to_unprotected_subobjects__ = 0 self.assertRaises(Unauthorized, self.scaling.guarded_orig_image, 'image') self.item.__allow_access_to_unprotected_subobjects__ = 1 def testGetAvailableSizes(self): self.scaling.available_sizes = {'foo': (60, 60)} assert self.scaling.getAvailableSizes('image') == {'foo': (60, 60)} def testGetImageSize(self): assert self.scaling.getImageSize('image') == (200, 200) def testGetOriginalScaleTag(self): tag = self.scaling.tag('image') base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="foo" title="foo" height="(\d+)" width="(\d+)" />'.format( base, ) self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithNonASCIITitle(self): self.item.title = u'ü' tag = self.scaling.tag('image') base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />'.format( base, ) self.assertTrue(re.match(expected, tag).groups()) def testScaleOnItemWithUnicodeTitle(self): self.item.Title = lambda: u'ü' tag = self.scaling.tag('image') base = self.item.absolute_url() expected = \ r'<img src="{0}/@@images/([-0-9a-f]{{36}}).(jpeg|gif|png)" ' \ r'alt="\xfc" title="\xfc" height="(\d+)" width="(\d+)" />'.format( base, ) self.assertTrue(re.match(expected, tag).groups()) def testScaledJpegImageQuality(self): """Test image quality setting for jpeg images. Image quality not available for PNG images. """ data = getFile('image.jpg') item = DummyContent() item.image = NamedImage(data, 'image/png', u'image.jpg') scaling = ImageScaling(item, None) # scale an image, record its size foo = scaling.scale('image', width=100, height=80) size_foo = foo.data.getSize() # let's pretend p.a.imaging set the scaling quality to "really sloppy" gsm = getGlobalSiteManager() qualitySupplier = DummyQualitySupplier() gsm.registerUtility(qualitySupplier.getQuality, IScaledImageQuality) wait_to_ensure_modified() # now scale again bar = scaling.scale('image', width=100, height=80) size_bar = bar.data.getSize() # first one should be bigger self.assertTrue(size_foo > size_bar) def testOversizedHighPixelDensityScale(self): orig_size = max(self.scaling.getImageSize('image')) scale_size = orig_size / 2 self.scaling.getHighPixelDensityScales = lambda: [ {'scale': 2, 'quality': 66}, {'scale': 3, 'quality': 66}] foo = self.scaling.scale('image', width=scale_size, height=scale_size) self.assertEqual(len(foo.srcset), 1) self.assertEqual(foo.srcset[0]['scale'], 2)