# Path: chat/exc.py
# class SkygearChatException(SkygearException):
#     pass
# 
# Path: chat/message_handlers.py
# def handle_message_before_save(record, original_record, conn):
#     message = Message.from_record(record)
# 
#     if original_record is not None and original_record['deleted']:
#         raise AlreadyDeletedException()
# 
#     if UserConversation.fetch_one(message.conversation_id) is None:
#         raise NotInConversationException()
# 
#     if original_record is None:
#         message['deleted'] = False
#         message['revision'] = 1
#     else:
#         message_history = MessageHistory(Message.from_record(original_record))
#         message_history.save()
#     message['edited_at'] = datetime.utcnow()
#     message['edited_by'] = Reference(RecordID('user', current_user_id()))
# 
#     if message.get('message_status', None) is None:
#         message['message_status'] = 'delivered'
# 
#     # TODO use proper ACL setter
#     message._acl = Conversation.get_message_acl(message.conversation_id)
# 
#     # py-skygear save hook use the original record refs
#     # so we need to apply all the changes from message object to record
#     message.to_record(record)
#     return record
# 
# Path: chat/message_history.py
# class MessageHistory(ChatRecord):
#     record_type = 'message_history'
# 
#     def __init__(self, message):
#         super().__init__(RecordID(self.record_type, str(uuid.uuid4())),
#                          current_user_id(),
#                          message.acl)
#         for key in ['attachment', 'body', 'metadata',
#                     'conversation', 'message_status',
#                     'edited_by', 'edited_at']:
#             if key in message:
#                 self[key] = message.get(key, None)
#         self['parent'] = Reference(message.id)


import unittest
from unittest.mock import Mock, patch
from skygear.encoding import deserialize_record
from ..exc import SkygearChatException
from ..message_handlers import handle_message_before_save
from ..message_history import MessageHistory
            each_patcher.stop()

    def record(self):
        return deserialize_record({
            '_id': 'message/1',
            '_access': None,
            '_ownerID': 'user1',
            'conversation': {
                '$type': 'ref',
                '$id': 'conversation/1'
            },
            'body': 'hihi',
            'deleted': False
        })

    def original_record(self):
        return deserialize_record({
            '_id': 'message/1',
            '_access': None,
            '_ownerID': 'user1',
            'conversation': {
                '$type': 'ref',
                '$id': 'conversation/1'
            },
            'body': 'hihi',
            'deleted': False
        })

    @patch('chat.message.UserConversation.fetch_one', Mock(return_value=None))
    def test_user_not_in_conversation(self):

# Path: chat/exc.py
# class SkygearChatException(SkygearException):
#     pass
# 
# Path: chat/message_handlers.py
# def handle_message_before_save(record, original_record, conn):
#     message = Message.from_record(record)
# 
#     if original_record is not None and original_record['deleted']:
#         raise AlreadyDeletedException()
# 
#     if UserConversation.fetch_one(message.conversation_id) is None:
#         raise NotInConversationException()
# 
#     if original_record is None:
#         message['deleted'] = False
#         message['revision'] = 1
#     else:
#         message_history = MessageHistory(Message.from_record(original_record))
#         message_history.save()
#     message['edited_at'] = datetime.utcnow()
#     message['edited_by'] = Reference(RecordID('user', current_user_id()))
# 
#     if message.get('message_status', None) is None:
#         message['message_status'] = 'delivered'
# 
#     # TODO use proper ACL setter
#     message._acl = Conversation.get_message_acl(message.conversation_id)
# 
#     # py-skygear save hook use the original record refs
#     # so we need to apply all the changes from message object to record
#     message.to_record(record)
#     return record
# 
# Path: chat/message_history.py
# class MessageHistory(ChatRecord):
#     record_type = 'message_history'
# 
#     def __init__(self, message):
#         super().__init__(RecordID(self.record_type, str(uuid.uuid4())),
#                          current_user_id(),
#                          message.acl)
#         for key in ['attachment', 'body', 'metadata',
#                     'conversation', 'message_status',
#                     'edited_by', 'edited_at']:
#             if key in message:
#                 self[key] = message.get(key, None)
#         self['parent'] = Reference(message.id)


# Path: chat/test/test_handle_message_before_save.py
import unittest
from unittest.mock import Mock, patch
from skygear.encoding import deserialize_record
from ..exc import SkygearChatException
from ..message_handlers import handle_message_before_save
from ..message_history import MessageHistory

            each_patcher.stop()

    def record(self):
        return deserialize_record({
            '_id': 'message/1',
            '_access': None,
            '_ownerID': 'user1',
            'conversation': {
                '$type': 'ref',
                '$id': 'conversation/1'
            },
            'body': 'hihi',
            'deleted': False
        })

    def original_record(self):
        return deserialize_record({
            '_id': 'message/1',
            '_access': None,
            '_ownerID': 'user1',
            'conversation': {
                '$type': 'ref',
                '$id': 'conversation/1'
            },
            'body': 'hihi',
            'deleted': False
        })

    @patch('chat.message.UserConversation.fetch_one', Mock(return_value=None))
    def test_user_not_in_conversation(self):

        with self.assertRaises(SkygearChatException) as cm: