import unittest
import manage_sys_paths
import json

from messaging.MessageHandler import MessageHandler

class DummyMongoRepo:
    '''Dummy class to be used for testing the MessageHandler'''
    last_trace = None
    def insert_trace(self, trace):
        self.last_trace = trace

from messaging.DummyMessageManager import DummyMessageManager as DummyMessageSender

class Test_MessageHandler(unittest.TestCase):
    handler = None
    repo = None
    msg_sender = None

    def setUp(self):
        self.repo = DummyMongoRepo()
        self.msg_sender = DummyMessageSender.get_instance()
        self.handler = MessageHandler(self.repo, self.msg_sender)

    def test_handleGeneric_emptyMessage_NotJsonError(self):
        res = self.handler.handle_generic('')
        self.assertEqual(self.handler.MSG_NOT_JSON, res)

    def test_handleGeneric_noneMessage_NotJsonError(self):
        res = self.handler.handle_generic(None)
        self.assertEqual(self.handler.MSG_NOT_JSON, res)

    def test_handleGeneric_emptyJson1_NoTypeFieldError(self):
        message = json.dumps({})
        res = self.handler.handle_generic(message)
        self.assertEqual(self.handler.MSG_NO_TYPE, res)

    def test_handleGeneric_emptyJson2_NoTypeFieldError(self):
        message = json.dumps('')
        res = self.handler.handle_generic(message)
        self.assertEqual(self.handler.MSG_NO_TYPE, res)

    def test_handleGeneric_missingTypeJson_NoTypeFieldError(self):
        message = json.dumps({'test': 'content'})
        res = self.handler.handle_generic(message)
        self.assertEqual(self.handler.MSG_NO_TYPE, res)

    def test_handleGeneric_randomType1_NotProcessed(self):
        message = json.dumps({'type': ''})
        res = self.handler.handle_generic(message)
        self.assertEqual(self.handler.MSG_NOT_PROCESSED, res)

    def test_handleGeneric_randomType2_NotProcessed(self):
        message = json.dumps({'type': 'test'})
        res = self.handler.handle_generic(message)
        self.assertEqual(self.handler.MSG_NOT_PROCESSED, res)

    def test_handleGeneric_randomTypeWithOtherField_NotProcessed(self):
        message = json.dumps({'type': 'test', 'other': 'content'})
        res = self.handler.handle_generic(message)
        self.assertEqual(self.handler.MSG_NOT_PROCESSED, res)

    def _get_valid_message(self) -> str:
        message_values = \
        { 'type': 'blockchain-transaction',
          'content': 
            {
            "ApplicationType": "string",
            "Metadata": {},
            "ResourceIds": "string",
            "ResourceMd5": "string",
            "ResourceState": "string",
            "Timestamp": "2019-08-27T14:00:48.587Z",
            "TransactionFrom": "string",
            "TransactionFromLatLng": "string",
            "TransactionId": "string",
            "TransactionTo": "string",
            "TransactionToLatLng": "string",
            "TransferredAsset": "string"
            }
        }
        return json.dumps(message_values)

    def test_handleGeneric_correctTraceContent_ProcessedResult(self):
        res = self.handler.handle_generic(self._get_valid_message())
        self.assertEqual(self.handler.MSG_TRACE_PROCESSED, res)

    def test_handleGeneric_correctTraceContent_AddedToRepo(self):
        msg = self._get_valid_message()
        _ = self.handler.handle_generic(msg)

        trace = json.loads(msg)['content']
        self.assertEqual(trace, self.repo.last_trace)

    def test_handleGeneric_correctTraceContent_NotificationSentCorrectly(self):
        msg = self._get_valid_message()
        _ = self.handler.handle_generic(msg)

        self.assertEqual('datahub', self.msg_sender.last_message['ex'])
        self.assertEqual('semantic-linking', self.msg_sender.last_message['key'])
        self.assertEqual(json.dumps({'type': 'new-traces-available'}), self.msg_sender.last_message['msg'])

if __name__ == '__main__':
    unittest.main()