Example #1
0
 def test_filter_on_multi_field_index_fields(self):
     # Test that we can filter on all index fields
     # TODO: Test filtering on subfields of IndexedField
     item = self.get_test_item()
     fields = []
     for f in self._reduce_fields_for_filter(item, self.get_item_fields()):
         if not issubclass(f.value_cls, MultiFieldIndexedElement):
             continue
         fields.append(f)
     if not fields:
         self.skipTest('No matching multi index fields on this model')
     item.save()
     common_qs = self.test_folder.filter(categories__contains=self.categories)
     for f in fields:
         val = getattr(item, f.name)
         # Filter multi-value fields with =, __in and __contains
         # For these, we need to filter on the subfield
         filter_kwargs = []
         for v in val:
             for subfield in f.value_cls.supported_fields(version=self.account.version):
                 field_path = FieldPath(field=f, label=v.label, subfield=subfield)
                 path, subval = field_path.path, field_path.get_value(item)
                 if subval is None:
                     continue
                 filter_kwargs.extend([
                     {path: subval}, {'%s__in' % path: [subval]}, {'%s__contains' % path: [subval]}
                 ])
         self._run_filter_tests(common_qs, f, filter_kwargs, val)
 def test_filter_on_single_field_index_fields(self):
     # Test that we can filter on all index fields
     item = self.get_test_item()
     fields = []
     for f in self._reduce_fields_for_filter(item, self.get_item_fields()):
         if not issubclass(f.value_cls, SingleFieldIndexedElement):
             continue
         fields.append(f)
     if not fields:
         self.skipTest("No matching single index fields on this model")
     item.save()
     common_qs = self.test_folder.filter(
         categories__contains=self.categories)
     for f in fields:
         val = getattr(item, f.name)
         # For these, we may filter by item or subfield value
         filter_kwargs = []
         for v in val:
             for subfield in f.value_cls.supported_fields(
                     version=self.account.version):
                 field_path = FieldPath(field=f,
                                        label=v.label,
                                        subfield=subfield)
                 path, subval = field_path.path, field_path.get_value(item)
                 if subval is None:
                     continue
                 filter_kwargs.extend([
                     {
                         f.name: v
                     },
                     {
                         path: subval
                     },
                     {
                         f"{path}__in": [subval]
                     },
                     {
                         f"{path}__contains": get_random_substring(subval)
                     },
                 ])
         self._run_filter_tests(common_qs, f, filter_kwargs, val)
 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",
     )
Example #4
0
    def test_fetch(self):
        item = self.get_test_item()
        self.test_folder.bulk_create(items=[item, item])
        ids = self.test_folder.filter(categories__contains=item.categories)
        items = list(self.account.fetch(ids=ids))
        for item in items:
            self.assertIsInstance(item, self.ITEM_CLASS)
        self.assertEqual(len(items), 2)

        items = list(self.account.fetch(ids=ids, only_fields=['subject']))
        self.assertEqual(len(items), 2)

        items = list(self.account.fetch(ids=ids, only_fields=[FieldPath.from_string('subject', self.test_folder)]))
        self.assertEqual(len(items), 2)

        items = list(self.account.fetch(ids=ids, only_fields=['id', 'changekey']))
        self.assertEqual(len(items), 2)
Example #5
0
 def test_filter_on_all_fields(self):
     # Test that we can filter on all field names
     # TODO: Test filtering on subfields of IndexedField
     item = self.get_test_item().save()
     common_qs = self.test_folder.filter(
         categories__contains=self.categories)
     for f in self.get_item_fields():
         if not f.supports_version(self.account.version):
             # Cannot be used with this EWS version
             continue
         if not f.is_searchable:
             # Cannot be used in a QuerySet
             continue
         val = getattr(item, f.name)
         if val is None:
             # We cannot filter on None values
             continue
         if self.ITEM_CLASS == Contact and f.name in ('body',
                                                      'display_name'):
             # filtering 'body' or 'display_name' on Contact items doesn't work at all. Error in EWS?
             continue
         if f.is_list:
             # Filter multi-value fields with =, __in and __contains
             if issubclass(f.value_cls, MultiFieldIndexedElement):
                 # For these, we need to filter on the subfield
                 filter_kwargs = []
                 for v in val:
                     for subfield in f.value_cls.supported_fields(
                             version=self.account.version):
                         field_path = FieldPath(field=f,
                                                label=v.label,
                                                subfield=subfield)
                         path, subval = field_path.path, field_path.get_value(
                             item)
                         if subval is None:
                             continue
                         filter_kwargs.extend([{
                             path: subval
                         }, {
                             '%s__in' % path: [subval]
                         }, {
                             '%s__contains' % path: [subval]
                         }])
             elif issubclass(f.value_cls, SingleFieldIndexedElement):
                 # For these, we may filter by item or subfield value
                 filter_kwargs = []
                 for v in val:
                     for subfield in f.value_cls.supported_fields(
                             version=self.account.version):
                         field_path = FieldPath(field=f,
                                                label=v.label,
                                                subfield=subfield)
                         path, subval = field_path.path, field_path.get_value(
                             item)
                         if subval is None:
                             continue
                         filter_kwargs.extend([{
                             f.name: v
                         }, {
                             path: subval
                         }, {
                             '%s__in' % path: [subval]
                         }, {
                             '%s__contains' % path: [subval]
                         }])
             else:
                 filter_kwargs = [{
                     '%s__in' % f.name: val
                 }, {
                     '%s__contains' % f.name: val
                 }]
         else:
             # Filter all others with =, __in and __contains. We could have more filters here, but these should
             # always match.
             filter_kwargs = [{f.name: val}, {'%s__in' % f.name: [val]}]
             if isinstance(f, TextField) and not isinstance(f, ChoiceField):
                 # Choice fields cannot be filtered using __contains. Sort of makes sense.
                 random_start = get_random_int(min_val=0,
                                               max_val=len(val) // 2)
                 random_end = get_random_int(min_val=len(val) // 2 + 1,
                                             max_val=len(val))
                 filter_kwargs.append({
                     '%s__contains' % f.name:
                     val[random_start:random_end]
                 })
         for kw in filter_kwargs:
             with self.subTest(f=f, kw=kw):
                 matches = common_qs.filter(**kw).count()
                 if isinstance(f, TextField) and f.is_complex:
                     # Complex text fields sometimes fail a search using generated data. In production,
                     # they almost always work anyway. Give it one more try after 10 seconds; it seems EWS does
                     # some sort of indexing that needs to catch up.
                     if not matches:
                         time.sleep(10)
                         matches = common_qs.filter(**kw).count()
                         if not matches and isinstance(f, BodyField):
                             # The body field is particularly nasty in this area. Give up
                             continue
                 self.assertEqual(matches, 1, (f.name, val, kw))