def test_attachment_properties(self): binary_file_content = u'Hello from unicode æøå'.encode('utf-8') att1 = FileAttachment(name='my_file_1.txt', content=binary_file_content) self.assertIn("name='my_file_1.txt'", str(att1)) att1.content = binary_file_content # Test property setter self.assertEqual(att1.content, binary_file_content) # Test property getter att1.attachment_id = 'xxx' self.assertEqual(att1.content, binary_file_content ) # Test property getter when attachment_id is set att1._content = None with self.assertRaises(ValueError): print(att1.content ) # Test property getter when we need to fetch the content attached_item1 = self.get_test_item(folder=self.test_folder) att2 = ItemAttachment(name='attachment1', item=attached_item1) self.assertIn("name='attachment1'", str(att2)) att2.item = attached_item1 # Test property setter self.assertEqual(att2.item, attached_item1) # Test property getter self.assertEqual(att2.item, attached_item1) # Test property getter att2.attachment_id = 'xxx' self.assertEqual( att2.item, attached_item1) # Test property getter when attachment_id is set att2._item = None with self.assertRaises(ValueError): print(att2.item ) # Test property getter when we need to fetch the item
def test_file_attachments(self): item = self.get_test_item(folder=self.test_folder) # Test __init__(attachments=...) and attach() on new item binary_file_content = u'Hello from unicode æøå'.encode('utf-8') att1 = FileAttachment(name='my_file_1.txt', content=binary_file_content) self.assertEqual(len(item.attachments), 0) item.attach(att1) self.assertEqual(len(item.attachments), 1) item.save() fresh_item = list(self.account.fetch(ids=[item]))[0] self.assertEqual(len(fresh_item.attachments), 1) fresh_attachments = sorted(fresh_item.attachments, key=lambda a: a.name) self.assertEqual(fresh_attachments[0].name, 'my_file_1.txt') self.assertEqual(fresh_attachments[0].content, binary_file_content) # Test raw call to service self.assertEqual( list( GetAttachment(account=item.account).call( items=[att1.attachment_id], include_mime_content=False))[0].find('{%s}Content' % TNS).text, 'SGVsbG8gZnJvbSB1bmljb2RlIMOmw7jDpQ==') # Test attach on saved object att2 = FileAttachment(name='my_file_2.txt', content=binary_file_content) self.assertEqual(len(item.attachments), 1) item.attach(att2) self.assertEqual(len(item.attachments), 2) fresh_item = list(self.account.fetch(ids=[item]))[0] self.assertEqual(len(fresh_item.attachments), 2) fresh_attachments = sorted(fresh_item.attachments, key=lambda a: a.name) self.assertEqual(fresh_attachments[0].name, 'my_file_1.txt') self.assertEqual(fresh_attachments[0].content, binary_file_content) self.assertEqual(fresh_attachments[1].name, 'my_file_2.txt') self.assertEqual(fresh_attachments[1].content, binary_file_content) # Test detach item.detach(att1) self.assertTrue(att1.attachment_id is None) self.assertTrue(att1.parent_item is None) fresh_item = list(self.account.fetch(ids=[item]))[0] self.assertEqual(len(fresh_item.attachments), 1) fresh_attachments = sorted(fresh_item.attachments, key=lambda a: a.name) self.assertEqual(fresh_attachments[0].name, 'my_file_2.txt') self.assertEqual(fresh_attachments[0].content, binary_file_content)
def test_file_attachment_properties(self): binary_file_content = 'Hello from unicode æøå'.encode('utf-8') att1 = FileAttachment(name='my_file_1.txt', content=binary_file_content) self.assertIn("name='my_file_1.txt'", str(att1)) att1.content = binary_file_content # Test property setter self.assertEqual(att1.content, binary_file_content) # Test property getter att1.attachment_id = 'xxx' self.assertEqual(att1.content, binary_file_content ) # Test property getter when attachment_id is set att1._content = None with self.assertRaises(ValueError): print(att1.content ) # Test property getter when we need to fetch the content
def test_detach_all(self): # Make sure that we can detach all by passing item.attachments item = self.get_test_item(folder=self.test_folder).save() item.attach([FileAttachment(name="empty_file.txt", content=b"") for _ in range(6)]) self.assertEqual(len(item.attachments), 6) item.detach(item.attachments) self.assertEqual(len(item.attachments), 0)
def test_empty_file_attachment(self): item = self.get_test_item(folder=self.test_folder) att1 = FileAttachment(name='empty_file.txt', content=b'') item.attach(att1) item.save() fresh_item = self.get_item_by_id(item) self.assertEqual(fresh_item.attachments[0].content, b'')
def test_empty_file_attachment(self): item = self.get_test_item(folder=self.test_folder) att1 = FileAttachment(name='empty_file.txt', content=b'') item.attach(att1) item.save() fresh_item = list(self.account.fetch(ids=[item]))[0] self.assertEqual(fresh_item.attachments[0].content, b'')
def test_file_attachments(self): item = self.get_test_item(folder=self.test_folder) # Test __init__(attachments=...) and attach() on new item binary_file_content = 'Hello from unicode æøå'.encode('utf-8') att1 = FileAttachment(name='my_file_1.txt', content=binary_file_content) self.assertEqual(len(item.attachments), 0) item.attach(att1) self.assertEqual(len(item.attachments), 1) item.save() fresh_item = self.get_item_by_id(item) self.assertEqual(len(fresh_item.attachments), 1) fresh_attachments = sorted(fresh_item.attachments, key=lambda a: a.name) self.assertEqual(fresh_attachments[0].name, 'my_file_1.txt') self.assertEqual(fresh_attachments[0].content, binary_file_content) # Test attach on saved object att2 = FileAttachment(name='my_file_2.txt', content=binary_file_content) self.assertEqual(len(item.attachments), 1) item.attach(att2) self.assertEqual(len(item.attachments), 2) fresh_item = self.get_item_by_id(item) self.assertEqual(len(fresh_item.attachments), 2) fresh_attachments = sorted(fresh_item.attachments, key=lambda a: a.name) self.assertEqual(fresh_attachments[0].name, 'my_file_1.txt') self.assertEqual(fresh_attachments[0].content, binary_file_content) self.assertEqual(fresh_attachments[1].name, 'my_file_2.txt') self.assertEqual(fresh_attachments[1].content, binary_file_content) # Test detach item.detach(att1) self.assertTrue(att1.attachment_id is None) self.assertTrue(att1.parent_item is None) fresh_item = self.get_item_by_id(item) self.assertEqual(len(fresh_item.attachments), 1) fresh_attachments = sorted(fresh_item.attachments, key=lambda a: a.name) self.assertEqual(fresh_attachments[0].name, 'my_file_2.txt') self.assertEqual(fresh_attachments[0].content, binary_file_content)
def test_both_attachment_types(self): item = self.get_test_item(folder=self.test_folder) attached_item = self.get_test_item(folder=self.test_folder).save() item_attachment = ItemAttachment(name="item_attachment", item=attached_item) file_attachment = FileAttachment(name="file_attachment", content=b"file_attachment") item.attach(item_attachment) item.attach(file_attachment) item.save() fresh_item = self.get_item_by_id(item) self.assertSetEqual({a.name for a in fresh_item.attachments}, {"item_attachment", "file_attachment"})
def test_send_pre_2013(self): # Test < Exchange 2013 fallback for attachments and send-only mode item = self.get_test_item() item.account = self.get_account() item.folder = item.account.inbox item.attach( FileAttachment(name="file_attachment", content=b"file_attachment")) item.account.version = Version(EXCHANGE_2010_SP2) item.send(save_copy=False) self.assertIsNone(item.id) self.assertIsNone(item.changekey)
def test_both_attachment_types(self): item = self.get_test_item(folder=self.test_folder) attached_item = self.get_test_item(folder=self.test_folder).save() item_attachment = ItemAttachment(name='item_attachment', item=attached_item) file_attachment = FileAttachment(name='file_attachment', content=b'file_attachment') item.attach(item_attachment) item.attach(file_attachment) item.save() fresh_item = list(self.account.fetch(ids=[item]))[0] self.assertSetEqual({a.name for a in fresh_item.attachments}, {'item_attachment', 'file_attachment'})
def test_file_attachment_properties(self): binary_file_content = "Hello from unicode æøå".encode("utf-8") att1 = FileAttachment(name="my_file_1.txt", content=binary_file_content) self.assertIn("name='my_file_1.txt'", str(att1)) att1.content = binary_file_content # Test property setter with self.assertRaises(TypeError) as e: att1.content = "XXX" self.assertEqual(e.exception.args[0], "'value' 'XXX' must be of type <class 'bytes'>") self.assertEqual(att1.content, binary_file_content) # Test property getter att1.attachment_id = "xxx" self.assertEqual(att1.content, binary_file_content) # Test property getter when attachment_id is set att1._content = None with self.assertRaises(ValueError): print(att1.content) # Test property getter when we need to fetch the content
def test_pickle(self): # Test that we can pickle various objects item = Message(folder=self.account.inbox, subject='XXX', categories=self.categories).save() attachment = FileAttachment(name='pickle_me.txt', content=b'') for o in ( FaultTolerance(max_wait=3600), self.account.protocol, attachment, self.account.root, self.account.inbox, self.account, item, ): with self.subTest(o=o): pickled_o = pickle.dumps(o) unpickled_o = pickle.loads(pickled_o) self.assertIsInstance(unpickled_o, type(o)) if not isinstance(o, (Account, Protocol, FaultTolerance)): # __eq__ is not defined on some classes self.assertEqual(o, unpickled_o)
def test_streaming_file_attachments(self): item = self.get_test_item(folder=self.test_folder) large_binary_file_content = get_random_string(2 ** 10).encode("utf-8") large_att = FileAttachment(name="my_large_file.txt", content=large_binary_file_content) item.attach(large_att) item.save() # Test streaming file content fresh_item = self.get_item_by_id(item) with fresh_item.attachments[0].fp as fp: self.assertEqual(fp.read(), large_binary_file_content) # Test partial reads of streaming file content fresh_item = self.get_item_by_id(item) with fresh_item.attachments[0].fp as fp: chunked_reads = [] buffer = fp.read(7) while buffer: chunked_reads.append(buffer) buffer = fp.read(7) self.assertListEqual(chunked_reads, list(chunkify(large_binary_file_content, 7)))
def test_streaming_file_attachment_error(self): # Test that we can parse XML error responses in streaming mode. # Try to stram an attachment with malformed ID att = FileAttachment( parent_item=self.get_test_item(folder=self.test_folder), attachment_id=AttachmentId(id='AAMk='), name='dummy.txt', content=b'', ) with self.assertRaises(ErrorInvalidIdMalformed): with att.fp as fp: fp.read() # Try to stream a non-existent attachment att.attachment_id.id = \ 'AAMkADQyYzZmYmUxLTJiYjItNDg2Ny1iMzNjLTIzYWE1NDgxNmZhNABGAAAAAADUebQDarW2Q7G2Ji8hKofPBwAl9iKCsfCfS' \ 'a9cmjh+JCrCAAPJcuhjAABioKiOUTCQRI6Q5sRzi0pJAAHnDV3CAAABEgAQAN0zlxDrzlxAteU+kt84qOM=' with self.assertRaises(ErrorItemNotFound): with att.fp as fp: fp.read()
def __init__(self): # Get a logger log = logging.getLogger(__name__) # timestamps the message with current date and time time = self.convert_to_EWStime(datetime.now()) # Create a namedtuple to simulate exchangelib Mailbox object FakeSender = namedtuple("FakeSender", ["email_address"]) my_sender = FakeSender("*****@*****.**") self.m = exc.Message(subject="[AM] Test", item_id="DEF568", sender=my_sender, body="Test message", datetime_sent=time) log.info('Test message created') import os cwd = os.path.dirname(os.path.realpath(__file__)) # filenames = os.listdir(cwd+u"/calcs") dummy = os.path.join(cwd, 'calcs', 'Dummy.txt') actual = os.path.join(cwd, 'calcs', 'test.xlsx') myfiles = [actual] for myfile in myfiles: try: # os.chdir("./calcs") log.info("Accessing: %s" % myfile) f = open(myfile, mode='rb') file_contents = f.read() # suffix = random.randint(0,99999) att = FileAttachment(name=myfile, content=file_contents, attachment_id=AttachmentId()) self.m.attach(att) f.close() os.chdir("..") except IOError: log.error("Error opening file %s. Exiting." % myfile) import sys sys.exit(0)
def random_val(self, field): if isinstance(field, ExtendedPropertyField): if field.value_cls.property_type == 'StringArray': return [get_random_string(255) for _ in range(random.randint(1, 4))] if field.value_cls.property_type == 'IntegerArray': return [get_random_int(0, 256) for _ in range(random.randint(1, 4))] if field.value_cls.property_type == 'BinaryArray': return [get_random_string(255).encode() for _ in range(random.randint(1, 4))] if field.value_cls.property_type == 'String': return get_random_string(255) if field.value_cls.property_type == 'Integer': return get_random_int(0, 256) if field.value_cls.property_type == 'Binary': # In the test_extended_distinguished_property test, EWS rull return 4 NULL bytes after char 16 if we # send a longer bytes sequence. return get_random_string(16).encode() raise ValueError('Unsupported field %s' % field) if isinstance(field, URIField): return get_random_url() if isinstance(field, EmailAddressField): return get_random_email() if isinstance(field, ChoiceField): return get_random_choice(field.supported_choices(version=self.account.version)) if isinstance(field, CultureField): return get_random_choice(['da-DK', 'de-DE', 'en-US', 'es-ES', 'fr-CA', 'nl-NL', 'ru-RU', 'sv-SE']) if isinstance(field, BodyField): return get_random_string(400) if isinstance(field, CharListField): return [get_random_string(16) for _ in range(random.randint(1, 4))] if isinstance(field, TextListField): return [get_random_string(400) for _ in range(random.randint(1, 4))] if isinstance(field, CharField): return get_random_string(field.max_length) if isinstance(field, TextField): return get_random_string(400) if isinstance(field, MimeContentField): return get_random_string(400).encode('utf-8') if isinstance(field, Base64Field): return get_random_bytes(400) if isinstance(field, BooleanField): return get_random_bool() if isinstance(field, DecimalField): return get_random_decimal(field.min or 1, field.max or 99) if isinstance(field, IntegerField): return get_random_int(field.min or 0, field.max or 256) if isinstance(field, DateField): return get_random_date() if isinstance(field, DateTimeBackedDateField): return get_random_date() if isinstance(field, DateTimeField): return get_random_datetime(tz=self.account.default_timezone) if isinstance(field, AttachmentField): return [FileAttachment(name='my_file.txt', content=get_random_string(400).encode('utf-8'))] if isinstance(field, MailboxListField): # email_address must be a real account on the server(?) # TODO: Mailbox has multiple optional args but vals must match server account, so we can't easily test if get_random_bool(): return [Mailbox(email_address=self.account.primary_smtp_address)] return [self.account.primary_smtp_address] if isinstance(field, MailboxField): # email_address must be a real account on the server(?) # TODO: Mailbox has multiple optional args but vals must match server account, so we can't easily test if get_random_bool(): return Mailbox(email_address=self.account.primary_smtp_address) return self.account.primary_smtp_address if isinstance(field, AttendeesField): # Attendee must refer to a real mailbox on the server(?). We're only sure to have one if get_random_bool(): mbx = Mailbox(email_address=self.account.primary_smtp_address) else: mbx = self.account.primary_smtp_address with_last_response_time = get_random_bool() if with_last_response_time: return [ Attendee(mailbox=mbx, response_type='Accept', last_response_time=get_random_datetime(tz=self.account.default_timezone)) ] if get_random_bool(): return [Attendee(mailbox=mbx, response_type='Accept')] return [self.account.primary_smtp_address] if isinstance(field, EmailAddressesField): addrs = [] for label in EmailAddress.get_field_by_fieldname('label').supported_choices(version=self.account.version): addr = EmailAddress(email=get_random_email()) addr.label = label addrs.append(addr) return addrs if isinstance(field, PhysicalAddressField): addrs = [] for label in PhysicalAddress.get_field_by_fieldname('label')\ .supported_choices(version=self.account.version): addr = PhysicalAddress(street=get_random_string(32), city=get_random_string(32), state=get_random_string(32), country=get_random_string(32), zipcode=get_random_string(8)) addr.label = label addrs.append(addr) return addrs if isinstance(field, PhoneNumberField): pns = [] for label in PhoneNumber.get_field_by_fieldname('label').supported_choices(version=self.account.version): pn = PhoneNumber(phone_number=get_random_string(16)) pn.label = label pns.append(pn) return pns if isinstance(field, EWSElementField): if field.value_cls == Recurrence: return Recurrence(pattern=DailyPattern(interval=5), start=get_random_date(), number=7) if field.value_cls == TaskRecurrence: return TaskRecurrence(pattern=DailyRegeneration(interval=5), start=get_random_date(), number=7) if field.value_cls == ReminderMessageData: start = get_random_time() end = get_random_time(start_time=start) return ReminderMessageData( reminder_text=get_random_string(16), location=get_random_string(16), start_time=start, end_time=end, ) if field.value_cls == CompleteName: return CompleteName( title=get_random_string(16), first_name=get_random_string(16), middle_name=get_random_string(16), last_name=get_random_string(16), suffix=get_random_string(16), initials=get_random_string(16), full_name=get_random_string(16), nickname=get_random_string(16), yomi_first_name=get_random_string(16), yomi_last_name=get_random_string(16), ) if isinstance(field, TimeZoneField): while True: tz = zoneinfo.ZoneInfo(random.choice(tuple(zoneinfo.available_timezones()))) try: EWSTimeZone.from_zoneinfo(tz) except UnknownTimeZone: continue return tz if isinstance(field, PermissionSetField): return PermissionSet( permissions=[ Permission( user_id=UserId(primary_smtp_address=self.account.primary_smtp_address), ) ] ) raise ValueError('Unknown field %s' % field)
def _attach(self, message: Message, attachments: Dict[str, str]): for name, attachment in attachments.items(): with open(attachment) as f: message.attach( FileAttachment(name=name, content=f.read().encode('utf-8')))
def test_detach_with_refresh(self): # Make sure that we can detach after refresh item = self.get_test_item(folder=self.test_folder).save() item.attach(FileAttachment(name='empty_file.txt', content=b'')) item.refresh() item.detach(item.attachments)
def test_attachment_failure(self): att1 = FileAttachment(name="my_file_1.txt", content="Hello from unicode æøå".encode("utf-8")) att1.attachment_id = "XXX" with self.assertRaises(ValueError) as e: att1.attach() self.assertEqual(e.exception.args[0], "This attachment has already been created") att1.attachment_id = None with self.assertRaises(ValueError) as e: att1.attach() self.assertEqual(e.exception.args[0], "Parent item None must have an account") att1.parent_item = Item() with self.assertRaises(ValueError) as e: att1.attach() self.assertEqual(e.exception.args[0], "Parent item Item(attachments=[]) must have an account") att1.parent_item = None with self.assertRaises(ValueError) as e: att1.detach() self.assertEqual(e.exception.args[0], "This attachment has not been created") att1.attachment_id = "XXX" with self.assertRaises(ValueError) as e: att1.detach() self.assertEqual(e.exception.args[0], "Parent item None must have an account") att1.parent_item = Item() with self.assertRaises(ValueError) as e: att1.detach() self.assertEqual(e.exception.args[0], "Parent item Item(attachments=[]) must have an account") att1.parent_item = "XXX" with self.assertRaises(TypeError) as e: att1.clean() self.assertEqual( e.exception.args[0], "'parent_item' 'XXX' must be of type <class 'exchangelib.items.item.Item'>" ) with self.assertRaises(ValueError) as e: Message(attachments=[att1]) self.assertIn("must point to this item", e.exception.args[0]) att1.parent_item = None att1.attachment_id = None
def test_attachment_failure(self): att1 = FileAttachment(name='my_file_1.txt', content='Hello from unicode æøå'.encode('utf-8')) att1.attachment_id = 'XXX' with self.assertRaises(ValueError): att1.attach() # Cannot have an attachment ID att1.attachment_id = None with self.assertRaises(ValueError): att1.attach() # Must have a parent item att1.parent_item = Item() with self.assertRaises(ValueError): att1.attach() # Parent item must have an account att1.parent_item = None with self.assertRaises(ValueError): att1.detach() # Must have an attachment ID att1.attachment_id = 'XXX' with self.assertRaises(ValueError): att1.detach() # Must have a parent item att1.parent_item = Item() with self.assertRaises(ValueError): att1.detach() # Parent item must have an account att1.parent_item = None att1.attachment_id = None
def test_magic(self): for item in (FileAttachment(name="XXX"), ItemAttachment(name="XXX")): self.assertIn("name=", str(item)) self.assertIn(item.__class__.__name__, repr(item))