<commit_before>import datetime

from exchangelib.attachments import ItemAttachment
from exchangelib.errors import ErrorItemNotFound, ErrorInternalServerError
from exchangelib.ewsdatetime import UTC_NOW
from exchangelib.extended_properties import ExtendedProperty, ExternId
from exchangelib.fields import ExtendedPropertyField, CharField
from exchangelib.folders import Inbox, FolderCollection
from exchangelib.items import CalendarItem, Message
from exchangelib.queryset import QuerySet
from exchangelib.restriction import Restriction, Q
from exchangelib.version import Build, EXCHANGE_2007, EXCHANGE_2013

from ..common import get_random_string, mock_version
from .test_basics import CommonItemTest


class GenericItemTest(CommonItemTest):
    # Tests that don't need to be run for every single folder type
    TEST_FOLDER = 'inbox'
    FOLDER_CLASS = Inbox
    ITEM_CLASS = Message

    def test_validation(self):
        item = self.get_test_item()
        item.clean()
        for f in self.ITEM_CLASS.FIELDS:
            with self.subTest(f=f):
                # Test field max_length
                if isinstance(f, CharField) and f.max_length:
                    with self.assertRaises(ValueError):
                        setattr(item, f.name, 'a' * (f.max_length + 1))
                        item.clean()
                        setattr(item, f.name, 'a')

    def test_invalid_direct_args(self):
        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.save()  # Must have account on save
        item = self.get_test_item()
        item.id = 'XXX'  # Fake a saved item
        item.account = None
        with self.assertRaises(ValueError):
            item.save()  # Must have account on update
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.save(update_fields=['foo', 'bar'])  # update_fields is only valid on update

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.refresh()  # Must have account on refresh
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.refresh()  # Refresh an item that has not been saved
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.refresh()  # Refresh an item that doesn't exist

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.copy(to_folder=self.test_folder)  # Must have an account on copy
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.copy(to_folder=self.test_folder)  # Must be an existing item
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.copy(to_folder=self.test_folder)  # Item disappeared

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.move(to_folder=self.test_folder)  # Must have an account on move
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.move(to_folder=self.test_folder)  # Must be an existing item
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.move(to_folder=self.test_folder)  # Item disappeared

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.delete()  # Must have an account
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.delete()  # Must be an existing item
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.delete()  # Item disappeared
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item._delete(delete_type='FOO', send_meeting_cancellations=None, affected_task_occurrences=None,
                         suppress_read_receipts=None)
        with self.assertRaises(ValueError):
            item.delete(send_meeting_cancellations='XXX')
        with self.assertRaises(ValueError):
            item._delete(affected_task_occurrences='XXX')
        with self.assertRaises(ValueError):
            item._delete(suppress_read_receipts='XXX')


    def test_invalid_kwargs_on_send(self):
        # Only Message class has the send() method
        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.send()  # Must have account on send
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.send()  # Item disappeared
        item = self.get_test_item()
        with self.assertRaises(AttributeError):
            item.send(copy_to_folder=self.account.trash, save_copy=False)  # Inconsistent args

    def test_unsupported_fields(self):
        # Create a field that is not supported by any current versions. Test that we fail when using this field
        class UnsupportedProp(ExtendedProperty):
            property_set_id = 'deadcafe-beef-beef-beef-deadcafebeef'
            property_name = 'Unsupported Property'<commit_msg>Fix test<commit_after>import datetime

from exchangelib.attachments import ItemAttachment
from exchangelib.errors import ErrorItemNotFound, ErrorInternalServerError
from exchangelib.ewsdatetime import UTC_NOW
from exchangelib.extended_properties import ExtendedProperty, ExternId
from exchangelib.fields import ExtendedPropertyField, CharField
from exchangelib.folders import Inbox, FolderCollection
from exchangelib.items import CalendarItem, Message
from exchangelib.queryset import QuerySet
from exchangelib.restriction import Restriction, Q
from exchangelib.version import Build, EXCHANGE_2007, EXCHANGE_2013

from ..common import get_random_string, mock_version
from .test_basics import CommonItemTest


class GenericItemTest(CommonItemTest):
    # Tests that don't need to be run for every single folder type
    TEST_FOLDER = 'inbox'
    FOLDER_CLASS = Inbox
    ITEM_CLASS = Message

    def test_validation(self):
        item = self.get_test_item()
        item.clean()
        for f in self.ITEM_CLASS.FIELDS:
            with self.subTest(f=f):
                # Test field max_length
                if isinstance(f, CharField) and f.max_length:
                    with self.assertRaises(ValueError):
                        setattr(item, f.name, 'a' * (f.max_length + 1))
                        item.clean()
                        setattr(item, f.name, 'a')

    def test_invalid_direct_args(self):
        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.save()  # Must have account on save
        item = self.get_test_item()
        item.id = 'XXX'  # Fake a saved item
        item.account = None
        with self.assertRaises(ValueError):
            item.save()  # Must have account on update
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.save(update_fields=['foo', 'bar'])  # update_fields is only valid on update

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.refresh()  # Must have account on refresh
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.refresh()  # Refresh an item that has not been saved
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.refresh()  # Refresh an item that doesn't exist

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.copy(to_folder=self.test_folder)  # Must have an account on copy
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.copy(to_folder=self.test_folder)  # Must be an existing item
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.copy(to_folder=self.test_folder)  # Item disappeared

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.move(to_folder=self.test_folder)  # Must have an account on move
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.move(to_folder=self.test_folder)  # Must be an existing item
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.move(to_folder=self.test_folder)  # Item disappeared

        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.delete()  # Must have an account
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item.delete()  # Must be an existing item
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.delete()  # Item disappeared
        item = self.get_test_item()
        with self.assertRaises(ValueError):
            item._delete(delete_type='FOO', send_meeting_cancellations=None, affected_task_occurrences=None,
                         suppress_read_receipts=None)
        with self.assertRaises(ValueError):
            item.delete(send_meeting_cancellations='XXX')
        with self.assertRaises(ValueError):
            item.delete(affected_task_occurrences='XXX')
        with self.assertRaises(ValueError):
            item.delete(suppress_read_receipts='XXX')


    def test_invalid_kwargs_on_send(self):
        # Only Message class has the send() method
        item = self.get_test_item()
        item.account = None
        with self.assertRaises(ValueError):
            item.send()  # Must have account on send
        item = self.get_test_item()
        item.save()
        item_id, changekey = item.id, item.changekey
        item.delete()
        item.id, item.changekey = item_id, changekey
        with self.assertRaises(ErrorItemNotFound):
            item.send()  # Item disappeared
        item = self.get_test_item()
        with self.assertRaises(AttributeError):
            item.send(copy_to_folder=self.account.trash, save_copy=False)  # Inconsistent args

    def test_unsupported_fields(self):
        # Create a field that is not supported by any current versions. Test that we fail when using this field
        class UnsupportedProp(ExtendedProperty):
            property_set_id = 'deadcafe-beef-beef-beef-deadcafebeef'
            property_name = 'Unsupported Property'
{'fraction_non_alphanumeric': 0.08327125237976989, 'fraction_numerical': 0.0014899428855227217, 'mean_word_length': 2.4979733642154023, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6591628', 'n_tokens_mistral': 3514, 'n_tokens_neox': 3405, 'n_words': 816}