def test_resolvenames(self): with self.assertRaises(ValueError): self.account.protocol.resolve_names(names=[], search_scope='XXX') with self.assertRaises(ValueError): self.account.protocol.resolve_names(names=[], shape='XXX') self.assertGreaterEqual( self.account.protocol.resolve_names(names=['*****@*****.**']), []) self.assertEqual( self.account.protocol.resolve_names( names=[self.account.primary_smtp_address]), [Mailbox(email_address=self.account.primary_smtp_address)]) # Test something that's not an email self.assertEqual( self.account.protocol.resolve_names(names=['foo\\bar']), [ErrorNameResolutionNoResults('No results were found.')]) # Test return_full_contact_data mailbox, contact = self.account.protocol.resolve_names( names=[self.account.primary_smtp_address], return_full_contact_data=True)[0] self.assertEqual( mailbox, Mailbox(email_address=self.account.primary_smtp_address)) self.assertListEqual([ e.email.replace('SMTP:', '') for e in contact.email_addresses if e.label == 'EmailAddress1' ], [self.account.primary_smtp_address])
def test_resolvenames_parsing(self): # Test static XML since server has no roomlists ws = ResolveNames(self.account.protocol) xml = b'''\ <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <m:ResolveNamesResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"> <m:ResponseMessages> <m:ResolveNamesResponseMessage ResponseClass="Warning"> <m:MessageText>Multiple results were found.</m:MessageText> <m:ResponseCode>ErrorNameResolutionMultipleResults</m:ResponseCode> <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey> <m:ResolutionSet TotalItemsInView="2" IncludesLastItemInRange="true"> <t:Resolution> <t:Mailbox> <t:Name>John Doe</t:Name> <t:EmailAddress>[email protected]</t:EmailAddress> <t:RoutingType>SMTP</t:RoutingType> <t:MailboxType>Mailbox</t:MailboxType> </t:Mailbox> </t:Resolution> <t:Resolution> <t:Mailbox> <t:Name>John Deer</t:Name> <t:EmailAddress>[email protected]</t:EmailAddress> <t:RoutingType>SMTP</t:RoutingType> <t:MailboxType>Mailbox</t:MailboxType> </t:Mailbox> </t:Resolution> </m:ResolutionSet> </m:ResolveNamesResponseMessage> </m:ResponseMessages> </m:ResolveNamesResponse> </s:Body> </s:Envelope>''' _, body = ws._get_soap_parts(response=MockResponse(xml)) res = ws._get_elements_in_response(response=ws._get_soap_messages( body=body)) self.assertSetEqual( { Mailbox.from_xml(elem=elem.find(Mailbox.response_tag()), account=None).email_address for elem in res }, {'*****@*****.**', '*****@*****.**'})
def test_metrics(): metrics.stats.update(default_metrics) bad_message = Message(headers=None, sender=Mailbox(email_address='')) relay(bad_message, None) assert metrics.stats['message_ignore_count'] == 1 metrics.stats.update(default_metrics) bad_message = Message( headers=[MessageHeader(name='X-Autoreply', value='yes')], sender=Mailbox(email_address='')) relay(bad_message, None) assert metrics.stats['message_ignore_count'] == 1 fake_iris_client = IrisClient('http://localhost') good_message = Message(headers=[], sender=Mailbox(email_address=''), text_body='') with requests_mock.mock() as m: m.post('http://localhost/v0/response/email') metrics.stats.update(default_metrics) relay(good_message, fake_iris_client) assert metrics.stats['message_relay_success_count'] == 1 assert metrics.stats['incident_created_count'] == 0 with requests_mock.mock() as m: m.post('http://localhost/v0/response/email', headers={'X-IRIS-INCIDENT': '1234'}) metrics.stats.update(default_metrics) relay(good_message, fake_iris_client) assert metrics.stats['message_relay_success_count'] == 1 assert metrics.stats['incident_created_count'] == 1 with requests_mock.mock() as m: m.post('http://localhost/v0/response/email', status_code=500) metrics.stats.update(default_metrics) relay(good_message, fake_iris_client) assert metrics.stats['message_relay_failure_count'] == 1 with requests_mock.mock() as m: m.post('http://localhost/v0/response/email', status_code=400) metrics.stats.update(default_metrics) relay(good_message, fake_iris_client) assert metrics.stats['malformed_message_count'] == 1
def test_mailbox(self): mbx = Mailbox(name='XXX') with self.assertRaises(ValueError): mbx.clean() # Must have either item_id or email_address set mbx = Mailbox(email_address='XXX') self.assertEqual(hash(mbx), hash('xxx')) mbx.item_id = 'YYY' self.assertEqual(hash(mbx), hash('YYY')) # If we have an item_id, use that for uniqueness
def test_get_folders(self): folders = list(FolderCollection(account=self.account, folders=[self.account.root]).get_folders()) self.assertEqual(len(folders), 1, sorted(f.name for f in folders)) # Test that GetFolder can handle FolderId instances folders = list(FolderCollection(account=self.account, folders=[DistinguishedFolderId( id=Inbox.DISTINGUISHED_FOLDER_ID, mailbox=Mailbox(email_address=self.account.primary_smtp_address) )]).get_folders()) self.assertEqual(len(folders), 1, sorted(f.name for f in folders))
def test_expanddl(self): with self.assertRaises(ErrorNameResolutionNoResults): self.account.protocol.expand_dl("*****@*****.**") with self.assertRaises(ErrorNameResolutionNoResults): self.account.protocol.expand_dl( DLMailbox(email_address="*****@*****.**", mailbox_type="PublicDL")) xml = b"""\ <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <m:ExpandDLResponse ResponseClass="Success" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"> <m:ResponseMessages> <m:ExpandDLResponseMessage ResponseClass="Success"> <m:ResponseCode>NoError</m:ResponseCode> <m:DLExpansion TotalItemsInView="3" IncludesLastItemInRange="true"> <t:Mailbox> <t:Name>Foo Smith</t:Name> <t:EmailAddress>[email protected]</t:EmailAddress> <t:RoutingType>SMTP</t:RoutingType> <t:MailboxType>Mailbox</t:MailboxType> </t:Mailbox> <t:Mailbox> <t:Name>Bar Smith</t:Name> <t:EmailAddress>[email protected]</t:EmailAddress> <t:RoutingType>SMTP</t:RoutingType> <t:MailboxType>Mailbox</t:MailboxType> </t:Mailbox> </m:DLExpansion> </m:ExpandDLResponseMessage> </m:ResponseMessages> </ExpandDLResponse> </soap:Body> </soap:Envelope>""" self.assertListEqual( list(ExpandDL(protocol=self.account.protocol).parse(xml)), [ Mailbox(name="Foo Smith", email_address="*****@*****.**"), Mailbox(name="Bar Smith", email_address="*****@*****.**"), ], )
def test_get_folders_with_distinguished_id(self): # Test that we return an Inbox instance and not a generic Messages or Folder instance when we call GetFolder # with a DistinguishedFolderId instance with an ID of Inbox.DISTINGUISHED_FOLDER_ID. inbox = list(GetFolder(account=self.account).call( folders=[DistinguishedFolderId( id=Inbox.DISTINGUISHED_FOLDER_ID, mailbox=Mailbox(email_address=self.account.primary_smtp_address)) ], shape='IdOnly', additional_fields=[], ))[0] self.assertIsInstance(inbox, Inbox)
def test_mailbox(self): mbx = Mailbox(name="XXX") with self.assertRaises(ValueError): mbx.clean() # Must have either item_id or email_address set mbx = Mailbox(email_address="XXX") self.assertEqual(hash(mbx), hash("xxx")) mbx.item_id = "YYY" self.assertEqual( hash(mbx), hash("YYY")) # If we have an item_id, use that for uniqueness
def test_distribution_lists(self): dl = DistributionList(folder=self.test_folder, display_name=get_random_string(255), categories=self.categories) dl.save() new_dl = self.test_folder.get(categories__contains=dl.categories) self.assertEqual(new_dl.display_name, dl.display_name) self.assertEqual(new_dl.members, None) dl.refresh() dl.members = set( # We set mailbox_type to OneOff because otherwise the email address must be an actual account Member(mailbox=Mailbox(email_address=get_random_email(), mailbox_type='OneOff')) for _ in range(4) ) dl.save() new_dl = self.test_folder.get(categories__contains=dl.categories) self.assertEqual({m.mailbox.email_address for m in new_dl.members}, dl.members) dl.delete()
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 test_invalid_kwargs(self): with self.assertRaises(AttributeError): Mailbox(foo="XXX")
def test_resolvenames(self): with self.assertRaises(ValueError) as e: self.account.protocol.resolve_names(names=[], search_scope="XXX") self.assertEqual( e.exception.args[0], f"'search_scope' 'XXX' must be one of {sorted(SEARCH_SCOPE_CHOICES)}" ) with self.assertRaises(ValueError) as e: self.account.protocol.resolve_names(names=[], shape="XXX") self.assertEqual( e.exception.args[0], "'contact_data_shape' 'XXX' must be one of ['AllProperties', 'Default', 'IdOnly']" ) with self.assertRaises(ValueError) as e: ResolveNames(protocol=self.account.protocol, chunk_size=500).call(unresolved_entries=None) self.assertEqual( e.exception.args[0], "Chunk size 500 is too high. ResolveNames supports returning at most 100 candidates for a lookup", ) tmp = self.account.protocol.version self.account.protocol.config.version = Version(EXCHANGE_2010_SP1) with self.assertRaises(NotImplementedError) as e: self.account.protocol.resolve_names(names=["*****@*****.**"], shape="IdOnly") self.account.protocol.config.version = tmp self.assertEqual( e.exception.args[0], "'contact_data_shape' is only supported for Exchange 2010 SP2 servers and later" ) self.assertGreaterEqual( self.account.protocol.resolve_names(names=["*****@*****.**"]), []) self.assertGreaterEqual( self.account.protocol.resolve_names( names=["*****@*****.**"], search_scope="ActiveDirectoryContacts"), []) self.assertGreaterEqual( self.account.protocol.resolve_names(names=["*****@*****.**"], shape="AllProperties"), []) self.assertGreaterEqual( self.account.protocol.resolve_names( names=["*****@*****.**"], parent_folders=[self.account.contacts]), []) self.assertEqual( self.account.protocol.resolve_names( names=[self.account.primary_smtp_address]), [Mailbox(email_address=self.account.primary_smtp_address)], ) # Test something that's not an email self.assertEqual( self.account.protocol.resolve_names(names=["foo\\bar"]), [ErrorNameResolutionNoResults("No results were found.")], ) # Test return_full_contact_data mailbox, contact = self.account.protocol.resolve_names( names=[self.account.primary_smtp_address], return_full_contact_data=True)[0] self.assertEqual( mailbox, Mailbox(email_address=self.account.primary_smtp_address)) self.assertListEqual( [ e.email.replace("SMTP:", "") for e in contact.email_addresses if e.label == "EmailAddress1" ], [self.account.primary_smtp_address], )