'Test the callbacks of an exit.'

def test_exit(self):

    self.char1.key = 'char1'
    code = dedent('\n                                                if    character.key    ==    "char1":\n                                                                character.msg("You    can    leave.")\n                                                else:\n                                                                character.msg("You    cannot    leave.")\n                                                                deny()\n                                '.strip('\n'))
    self.exit.destination = self.room2
    self.handler.add_callback(self.exit, 'can_traverse', code, author=self.char1, valid=True)
    self.call(ExitCommand(), '', 'You    can    leave.', obj=self.exit)
    self.assertIs(self.char1.location, self.room2)
    self.call(ExitCommand(), '', 'You    cannot    leave.', obj=self.exit, caller=self.char2)
    self.assertIs(self.char2.location, self.room1)
    self.handler.del_callback(self.exit, 'can_traverse', 0)
    self.handler.add_callback(self.exit, 'traverse', "character.msg('Fine!')", author=self.char1, valid=True)
    self.call(ExitCommand(), '', obj=self.exit, caller=self.char2)
    self.assertIs(self.char2.location, self.room2)
    self.handler.del_callback(self.exit, 'traverse', 0)
    self.char1.location = self.room1
    self.char2.location = self.room1
    code = 'message    =    "{character}    goes    out."'
    self.handler.add_callback(self.exit, 'msg_leave', code, author=self.char1, valid=True)
    old_msg = self.char2.msg
    try:
        self.char2.msg = Mock()
        self.call(ExitCommand(), '', obj=self.exit)
        stored_msg = [(args[0] if (args and args[0]) else kwargs.get('text', utils.to_str(kwargs, force_string=True))) for (name, args, kwargs) in self.char2.msg.mock_calls]
        stored_msg = [(smsg[0] if isinstance(smsg, tuple) else smsg) for smsg in stored_msg]
        returned_msg = ansi.parse_ansi('\n'.join(stored_msg), strip_ansi=True)
        self.assertEqual(returned_msg, 'char1    goes    out.')
    finally:
        self.char2.msg = old_msg
    back = create_object('evennia.objects.objects.DefaultExit', key='in', location=self.room2, destination=self.room1)
    code = 'message    =    "{character}    goes    in."'
    self.handler.add_callback(self.exit, 'msg_arrive', code, author=self.char1, valid=True)
    old_msg = self.char2.msg
    try:
        self.char2.msg = Mock()
        self.call(ExitCommand(), '', obj=back)
        stored_msg = [(args[0] if (args and args[0]) else kwargs.get('text', utils.to_str(kwargs, force_string=True))) for (name, args, kwargs) in self.char2.msg.mock_calls]
        stored_msg = [(smsg[0] if isinstance(smsg, tuple) else smsg) for smsg in stored_msg]
        returned_msg = ansi.parse_ansi('\n'.join(stored_msg), strip_ansi=True)
        self.assertEqual(returned_msg, 'char1    goes    in.')
    finally:
        self.char2.msg = old_msg
