Exemple #1
0
    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
Exemple #2
0
    def test_recursive_attachments(self):
        # Test that we can handle an item which has an attached item, which has an attached item...
        item = self.get_test_item(folder=self.test_folder)
        attached_item_level_1 = self.get_test_item(folder=self.test_folder)
        attached_item_level_2 = self.get_test_item(folder=self.test_folder)
        attached_item_level_3 = self.get_test_item(folder=self.test_folder)

        attached_item_level_3.save()
        attachment_level_3 = ItemAttachment(name='attached_item_level_3',
                                            item=attached_item_level_3)
        attached_item_level_2.attach(attachment_level_3)
        attached_item_level_2.save()
        attachment_level_2 = ItemAttachment(name='attached_item_level_2',
                                            item=attached_item_level_2)
        attached_item_level_1.attach(attachment_level_2)
        attached_item_level_1.save()
        attachment_level_1 = ItemAttachment(name='attached_item_level_1',
                                            item=attached_item_level_1)
        item.attach(attachment_level_1)
        item.save()

        self.assertEqual(
            item.attachments[0].item.attachments[0].item.attachments[0].item.
            subject, attached_item_level_3.subject)

        # Also test a fresh item
        new_item = self.test_folder.get(id=item.id, changekey=item.changekey)
        self.assertEqual(
            new_item.attachments[0].item.attachments[0].item.attachments[0].
            item.subject, attached_item_level_3.subject)
Exemple #3
0
    def test_item_attachments(self):
        item = self.get_test_item(folder=self.test_folder)
        attached_item1 = self.get_test_item(folder=self.test_folder)
        att1 = ItemAttachment(name='attachment1', item=attached_item1)

        # Test __init__(attachments=...) and attach() on new item
        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, 'attachment1')
        self.assertEqual(fresh_attachments[0].item.subject,
                         attached_item1.subject)
        self.assertEqual(fresh_attachments[0].item.body, attached_item1.body)
        # Same as 'body' because 'body' doesn't contain HTML
        self.assertEqual(fresh_attachments[0].item.text_body,
                         attached_item1.body)

        # Test attach on saved object
        att2 = ItemAttachment(name='attachment2', item=attached_item1)
        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, 'attachment1')
        self.assertEqual(fresh_attachments[0].item.subject,
                         attached_item1.subject)
        self.assertEqual(fresh_attachments[0].item.body, attached_item1.body)
        self.assertEqual(fresh_attachments[1].name, 'attachment2')
        self.assertEqual(fresh_attachments[1].item.subject,
                         attached_item1.subject)
        self.assertEqual(fresh_attachments[1].item.body, attached_item1.body)

        # 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, 'attachment2')
        self.assertEqual(fresh_attachments[0].item.subject,
                         attached_item1.subject)
        self.assertEqual(fresh_attachments[0].item.body, attached_item1.body)
Exemple #4
0
 def test_item_attachment_properties(self):
     attached_item1 = self.get_test_item(folder=self.test_folder)
     att1 = ItemAttachment(name='attachment1', item=attached_item1)
     self.assertIn("name='attachment1'", str(att1))
     att1.item = attached_item1  # Test property setter
     self.assertEqual(att1.item, attached_item1)  # Test property getter
     self.assertEqual(att1.item, attached_item1)  # Test property getter
     att1.attachment_id = 'xxx'
     self.assertEqual(
         att1.item,
         attached_item1)  # Test property getter when attachment_id is set
     att1._item = None
     with self.assertRaises(ValueError):
         print(att1.item
               )  # Test property getter when we need to fetch the item
Exemple #5
0
def test_parse_incident_from_item_with_attachments():
    """
    Given:
        - Message item with attachment that contains email attachments

    When:
        - Parsing incident from item

    Verify:
        - Parsing runs successfully
    """
    content = b'ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901;' \
              b' d=microsoft.com; cv=none;b=ES/YXpFlV19rlN1iV+ORg5RzID8GPSQL' \
              b'nUT26MNdeTzcQSwK679doIz5Avpv8Ps2H/aBkBamwRNOCJBkl7iCHyy+04yRj3ghikw3u/ufIFHi0sQ7QG95mO1PVPLibv9A=='

    message = Message(
        datetime_created=EWSDate(year=2021, month=1, day=25),
        to_recipients=[],
        attachments=[
            ItemAttachment(
                item=Item(mime_content=content, headers=[]),
                attachment_id=AttachmentId(),
                last_modified_time=EWSDate(year=2021, month=1, day=25),
            ),
        ],
    )
    incident = parse_incident_from_item(message)
    assert incident['attachment']
Exemple #6
0
def test_parse_incident_from_item():
    """
    Given:
        - Message item with attachment that contains non UTF-8 encoded char

    When:
        - Parsing incident from item

    Verify:
        - Parsing runs successfully
        - Incidnet attachment is not empty
    """
    message = Message(
        datetime_created=EWSDate(year=2021, month=1, day=25),
        to_recipients=[],
        attachments=[
            ItemAttachment(
                item=Item(mime_content=b'\xc400'),
                attachment_id=AttachmentId(),
                last_modified_time=EWSDate(year=2021, month=1, day=25),
            ),
        ],
    )
    incident = parse_incident_from_item(message)
    assert incident['attachment']
    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"})
Exemple #8
0
    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_item_attachment_properties(self):
     attached_item1 = self.get_test_item(folder=self.test_folder)
     att1 = ItemAttachment(name="attachment1", item=attached_item1)
     self.assertIn("name='attachment1'", str(att1))
     att1.item = attached_item1  # Test property setter
     with self.assertRaises(TypeError) as e:
         att1.item = "XXX"
     self.assertEqual(e.exception.args[0], "'value' 'XXX' must be of type <class 'exchangelib.items.item.Item'>")
     self.assertEqual(att1.item, attached_item1)  # Test property getter
     self.assertEqual(att1.item, attached_item1)  # Test property getter
     att1.attachment_id = "xxx"
     self.assertEqual(att1.item, attached_item1)  # Test property getter when attachment_id is set
     att1._item = None
     with self.assertRaises(ValueError):
         print(att1.item)  # Test property getter when we need to fetch the item
 def test_raw_service_call(self):
     item = self.get_test_item(folder=self.test_folder)
     attached_item1 = self.get_test_item(folder=self.test_folder)
     attached_item1.body = HTMLBody("<html><body>Hello HTML</body></html>")
     att1 = ItemAttachment(name="attachment1", item=attached_item1)
     item.attach(att1)
     item.save()
     with self.assertRaises(ValueError):
         # Bad body_type
         GetAttachment(account=att1.parent_item.account).get(
             items=[att1.attachment_id],
             include_mime_content=True,
             body_type="XXX",
             filter_html_content=None,
             additional_fields=[],
         )
     # Test body_type
     attachment = GetAttachment(account=att1.parent_item.account).get(
         items=[att1.attachment_id],
         include_mime_content=True,
         body_type="Text",
         filter_html_content=None,
         additional_fields=[FieldPath(field=self.ITEM_CLASS.get_field_by_fieldname("body"))],
     )
     self.assertEqual(attachment.item.body, "Hello HTML\r\n")
     # Test filter_html_content. I wonder what unsafe HTML is.
     attachment = GetAttachment(account=att1.parent_item.account).get(
         items=[att1.attachment_id],
         include_mime_content=False,
         body_type="HTML",
         filter_html_content=True,
         additional_fields=[FieldPath(field=self.ITEM_CLASS.get_field_by_fieldname("body"))],
     )
     self.assertEqual(
         attachment.item.body,
         '<html>\r\n<head>\r\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\r\n'
         "</head>\r\n<body>\r\nHello HTML\r\n</body>\r\n</html>\r\n",
     )
Exemple #11
0
    def test_item_attachments(self):
        item = self.get_test_item(folder=self.test_folder)
        item.attachments = []

        attached_item1 = self.get_test_item(folder=self.test_folder)
        attached_item1.attachments = []
        attached_item1.save()
        attachment1 = ItemAttachment(name='attachment1', item=attached_item1)
        item.attach(attachment1)

        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, 'attachment1')
        self.assertIsInstance(fresh_attachments[0].item, self.ITEM_CLASS)

        for f in self.ITEM_CLASS.FIELDS:
            with self.subTest(f=f):
                # Normalize some values we don't control
                if f.is_read_only:
                    continue
                if self.ITEM_CLASS == CalendarItem and f in CalendarItem.timezone_fields(
                ):
                    # Timezone fields will (and must) be populated automatically from the timestamp
                    continue
                if isinstance(f, ExtendedPropertyField):
                    # Attachments don't have these values. It may be possible to request it if we can find the FieldURI
                    continue
                if f.name == 'is_read':
                    # This is always true for item attachments?
                    continue
                if f.name == 'reminder_due_by':
                    # EWS sets a default value if it is not set on insert. Ignore
                    continue
                if f.name == 'mime_content':
                    # This will change depending on other contents fields
                    continue
                old_val = getattr(attached_item1, f.name)
                new_val = getattr(fresh_attachments[0].item, f.name)
                if f.is_list:
                    old_val, new_val = set(old_val or ()), set(new_val or ())
                self.assertEqual(old_val, new_val, (f.name, old_val, new_val))

        # Test attach on saved object
        attached_item2 = self.get_test_item(folder=self.test_folder)
        attached_item2.attachments = []
        attached_item2.save()
        attachment2 = ItemAttachment(name='attachment2', item=attached_item2)
        item.attach(attachment2)

        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, 'attachment1')
        self.assertIsInstance(fresh_attachments[0].item, self.ITEM_CLASS)

        for f in self.ITEM_CLASS.FIELDS:
            with self.subTest(f=f):
                # Normalize some values we don't control
                if f.is_read_only:
                    continue
                if self.ITEM_CLASS == CalendarItem and f in CalendarItem.timezone_fields(
                ):
                    # Timezone fields will (and must) be populated automatically from the timestamp
                    continue
                if isinstance(f, ExtendedPropertyField):
                    # Attachments don't have these values. It may be possible to request it if we can find the FieldURI
                    continue
                if f.name == 'reminder_due_by':
                    # EWS sets a default value if it is not set on insert. Ignore
                    continue
                if f.name == 'is_read':
                    # This is always true for item attachments?
                    continue
                if f.name == 'mime_content':
                    # This will change depending on other contents fields
                    continue
                old_val = getattr(attached_item1, f.name)
                new_val = getattr(fresh_attachments[0].item, f.name)
                if f.is_list:
                    old_val, new_val = set(old_val or ()), set(new_val or ())
                self.assertEqual(old_val, new_val, (f.name, old_val, new_val))

        self.assertEqual(fresh_attachments[1].name, 'attachment2')
        self.assertIsInstance(fresh_attachments[1].item, self.ITEM_CLASS)

        for f in self.ITEM_CLASS.FIELDS:
            # Normalize some values we don't control
            if f.is_read_only:
                continue
            if self.ITEM_CLASS == CalendarItem and f in CalendarItem.timezone_fields(
            ):
                # Timezone fields will (and must) be populated automatically from the timestamp
                continue
            if isinstance(f, ExtendedPropertyField):
                # Attachments don't have these values. It may be possible to request it if we can find the FieldURI
                continue
            if f.name == 'reminder_due_by':
                # EWS sets a default value if it is not set on insert. Ignore
                continue
            if f.name == 'is_read':
                # This is always true for item attachments?
                continue
            if f.name == 'mime_content':
                # This will change depending on other contents fields
                continue
            old_val = getattr(attached_item2, f.name)
            new_val = getattr(fresh_attachments[1].item, f.name)
            if f.is_list:
                old_val, new_val = set(old_val or ()), set(new_val or ())
            self.assertEqual(old_val, new_val, (f.name, old_val, new_val))

        # Test detach
        item.detach(attachment2)
        self.assertTrue(attachment2.attachment_id is None)
        self.assertTrue(attachment2.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)

        for f in self.ITEM_CLASS.FIELDS:
            with self.subTest(f=f):
                # Normalize some values we don't control
                if f.is_read_only:
                    continue
                if self.ITEM_CLASS == CalendarItem and f in CalendarItem.timezone_fields(
                ):
                    # Timezone fields will (and must) be populated automatically from the timestamp
                    continue
                if isinstance(f, ExtendedPropertyField):
                    # Attachments don't have these values. It may be possible to request it if we can find the FieldURI
                    continue
                if f.name == 'reminder_due_by':
                    # EWS sets a default value if it is not set on insert. Ignore
                    continue
                if f.name == 'is_read':
                    # This is always true for item attachments?
                    continue
                if f.name == 'mime_content':
                    # This will change depending on other contents fields
                    continue
                old_val = getattr(attached_item1, f.name)
                new_val = getattr(fresh_attachments[0].item, f.name)
                if f.is_list:
                    old_val, new_val = set(old_val or ()), set(new_val or ())
                self.assertEqual(old_val, new_val, (f.name, old_val, new_val))

        # Test attach with non-saved item
        attached_item3 = self.get_test_item(folder=self.test_folder)
        attached_item3.attachments = []
        attachment3 = ItemAttachment(name='attachment2', item=attached_item3)
        item.attach(attachment3)
        item.detach(attachment3)
 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))