def test_content_type_validator(self): # guess content types from extension validator = ContentTypeValidator(['text/plain', 'image/jpeg']) analyzer = MagicAnalyzer() with AttachableDescriptor(io.BytesIO(b'Simple text')) as d: ctx = {} analyzer.process(d, ctx) validator.process(d, ctx) with AttachableDescriptor(self.cat_jpeg) as d: ctx = {} analyzer.process(d, ctx) validator.process(d, ctx) with AttachableDescriptor(self.cat_png) as d: ctx = {} analyzer.process(d, ctx) self.assertRaises( ContentTypeValidationError, validator.process, d, ctx ) self.assertRaises( ContentTypeValidationError, validator.process, d, {} )
def test_resize_reformat(self): # guess content types from extension with AttachableDescriptor(self.cat_png) as d: ctx = dict( length=100000, extension='.jpg', ) ImageProcessor(fmt='jpg', width=200).process(d, ctx) self.assertDictEqual( ctx, { 'content_type': 'image/jpeg', 'width': 200, 'height': 150, 'extension': '.jpg' }) with AttachableDescriptor(self.cat_jpeg) as d: # Checking when not modifying stream. ctx = dict() ImageProcessor().process(d, ctx) self.assertFalse(len(ctx)) # Checking when not modifying stream. ImageProcessor(fmt='jpeg').process(d, ctx) self.assertFalse(len(ctx)) ImageProcessor(fmt='jpeg', width=640).process(d, ctx) self.assertFalse(len(ctx)) ImageProcessor(fmt='jpeg', height=480).process(d, ctx) self.assertFalse(len(ctx))
def test_force_seekable(self): with mockup_http_static_server(self.cat_jpeg) as http_server: url = 'http://%s:%s' % http_server.server_address original_sum = md5sum(self.cat_jpeg) with AttachableDescriptor(url) as descriptor: descriptor.prepare_to_read(backend='file') self.assertEqual(original_sum, md5sum(descriptor)) with AttachableDescriptor(url) as descriptor: descriptor.prepare_to_read(backend='temp') self.assertEqual(original_sum, md5sum(descriptor)) with AttachableDescriptor(url) as descriptor: descriptor.prepare_to_read(backend='memory') self.assertEqual(original_sum, md5sum(descriptor)) with AttachableDescriptor(url) as descriptor: # Reading some bytes, before making the stream seekable descriptor.get_header_buffer() descriptor.prepare_to_read(backend='temp') self.assertEqual(original_sum, md5sum(descriptor)) with AttachableDescriptor(url) as descriptor: self.assertRaises(DescriptorOperationError, descriptor.prepare_to_read, backend='InvalidBackend') with open(self.dog_jpeg, 'rb') as f, AttachableDescriptor(url) as descriptor: descriptor.replace(f, position=1024) with open(self.dog_jpeg, 'rb') as f, AttachableDescriptor(url) as descriptor: descriptor.replace(f) self.assertEqual(md5sum(descriptor), md5sum(self.dog_jpeg))
def test_magic(self): # guess content types from extension analyzer = MagicAnalyzer() with AttachableDescriptor(io.BytesIO(b'Simple text')) as d: ctx = {} analyzer.process(d, ctx) self.assertEqual(ctx['content_type'], 'text/plain') with AttachableDescriptor(self.cat_jpeg) as d: ctx = {} analyzer.process(d, ctx) self.assertEqual(ctx['content_type'], 'image/jpeg') with AttachableDescriptor(self.cat_png) as d: ctx = {} analyzer.process(d, ctx) self.assertEqual(ctx['content_type'], 'image/png')
def test_wand(self): analyzer = WandAnalyzer() with AttachableDescriptor(self.cat_jpeg) as d: ctx = {} analyzer.process(d, ctx) self.assertDictEqual(ctx, { 'width': 640, 'height': 480, 'content_type': 'image/jpeg' })
def test_localfs(self): descriptor = AttachableDescriptor(self.cat_jpeg, width=100, height=80) self.assertIsInstance(descriptor, LocalFileSystemDescriptor) self.assertEqual(descriptor.filename, self.cat_jpeg) # Must be determined from the given file's extension: .jpg self.assertEqual(descriptor.content_type, 'image/jpeg') self.assertEqual(descriptor.original_filename, self.cat_jpeg) self.assertEqual(descriptor.width, 100) self.assertEqual(descriptor.height, 80) self.assertEqual(len(descriptor.get_header_buffer()), 1024) buffer = io.BytesIO() copy_stream(descriptor, buffer) buffer.seek(0) self.assertEqual(md5sum(buffer), md5sum(self.cat_jpeg))
def test_url(self): with mockup_http_static_server(self.cat_jpeg) as http_server: url = 'http://%s:%s' % http_server.server_address descriptor = AttachableDescriptor(url) self.assertIsInstance(descriptor, UrlDescriptor) self.assertEqual(descriptor.content_type, 'image/jpeg') # Must be determined from response headers self.assertEqual(descriptor.content_length, 70279) # Must be determined from response headers self.assertEqual(descriptor.original_filename, url)
def test_image_validator(self): # guess content types from extension analyzer = ImageAnalyzer() with AttachableDescriptor(self.dog_jpg) as d: ctx = {} analyzer.process(d, ctx) ImageValidator( (10, 10), (250, 250), content_types=['image/jpeg'] ).process(d, ctx) ImageValidator((10, 0), (0, 250)).process(d, ctx) ImageValidator((0, 0), (0, 250)).process(d, ctx) ImageValidator((0, 0), (0, 0)).process(d, ctx) # Lack of analyzer data self.assertRaises( DimensionValidationError, ImageValidator(maximum=(1, 0)).process, d, {} ) # Maximum self.assertRaises( DimensionValidationError, ImageValidator(maximum=(212, 0)).process, d, ctx ) self.assertRaises( DimensionValidationError, ImageValidator(maximum=(0, 159)).process, d, ctx ) # Minimum self.assertRaises( DimensionValidationError, ImageValidator(minimum=(214, 0)).process, d, ctx ) self.assertRaises( DimensionValidationError, ImageValidator(minimum=(0, 161)).process, d, ctx ) self.assertRaises( AspectRatioValidationError, ImageValidator(min_aspect_ratio=1.4).process, d, ctx ) self.assertRaises( AspectRatioValidationError, ImageValidator(max_aspect_ratio=1.3).process, d, ctx )
def test_crop(self): with AttachableDescriptor(self.cat_jpeg) as d: # Checking when not modifying stream. ctx = dict() ImageProcessor(crop=(160, 120, 480, 360)).process(d, ctx) ctx = dict() ImageAnalyzer().process(d, ctx) self.assertDictEqual(ctx, { 'content_type': 'image/jpeg', 'width': 320, 'height': 240, })
def test_crop(self): with AttachableDescriptor(self.cat_jpeg) as d: # Checking when not modifying stream. ctx = dict() ImageProcessor(crop=dict( width='50%', height='50%', gravity='center')).process(d, ctx) ctx = dict() WandAnalyzer().process(d, ctx) self.assertDictEqual(ctx, { 'content_type': 'image/jpeg', 'width': 320, 'height': 240, })
def test_stream(self): # guess content types from extension descriptor = AttachableDescriptor(io.BytesIO(b'Simple text'), extension='.txt') self.assertIsInstance(descriptor, StreamDescriptor) self.assertEqual(descriptor.content_type, 'text/plain') descriptor.seek(2) self.assertEqual(descriptor.tell(), 2) # guess extension from original filename descriptor = AttachableDescriptor(io.BytesIO(b'Simple text'), original_filename='letter.pdf') self.assertEqual(descriptor.extension, '.pdf') # guess extension from content type descriptor = AttachableDescriptor(io.BytesIO(b'Simple text'), content_type='application/json') self.assertEqual(descriptor.extension, '.json') self.assertRaises(DescriptorOperationError, lambda: descriptor.filename)
def test_cgi_field_storage(self): # encode a multipart form content_type, body, content_length = encode_multipart_data(files=dict(cat=self.cat_jpeg)) environ = { 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': content_type, 'CONTENT_LENGTH': content_length } storage = cgi.FieldStorage(body, environ=environ) descriptor = AttachableDescriptor(storage['cat']) self.assertIsInstance(descriptor, CgiFieldStorageDescriptor) self.assertEqual(descriptor.content_type, 'image/jpeg') self.assertEqual(descriptor.original_filename, split(self.cat_jpeg)[1]) buffer = io.BytesIO() copy_stream(descriptor, buffer) buffer.seek(0) self.assertEqual(md5sum(buffer), md5sum(self.cat_jpeg))
def test_non_seekable(self): class NonSeekableStream(io.BytesIO): def seekable(self, *args, **kwargs): return False inp = b'abcdefghijklmnopqrstuvwxyz' descriptor = AttachableDescriptor(NonSeekableStream(inp), header_buffer_size=10) # fetching header, it forces to cache header_buffer_size bytes from header. buffer = descriptor.get_header_buffer() self.assertEqual(buffer, b'abcdefghij') # fetching again to test the cache functionality buffer = descriptor.get_header_buffer() self.assertEqual(buffer, b'abcdefghij') out = b'' out += descriptor.read(9) self.assertEqual(descriptor.tell(), 9) out += descriptor.read(11) self.assertEqual(descriptor.tell(), 20) out += descriptor.read(10) self.assertEqual(out, inp) # Max length error descriptor = AttachableDescriptor(NonSeekableStream(inp), header_buffer_size=24, max_length=20) buffer = descriptor.get_header_buffer() self.assertEqual(buffer, b'abcdefghijklmnopqrstuvwx') self.assertRaises(MaximumLengthIsReachedError, descriptor.read, 1) # Test getting header buffer after read on non-seekable streams. descriptor = AttachableDescriptor(NonSeekableStream(inp), header_buffer_size=10, max_length=20) self.assertEqual(descriptor.read(10), b'abcdefghij') self.assertRaises(DescriptorOperationError, descriptor.get_header_buffer)