class Test_Config(B3TestCase):
    def setUp(self):
        B3TestCase.setUp(self)
        with logging_disabled():
            self.console.startup()

        logging.getLogger('output').setLevel(logging.DEBUG)

        self.conf = CfgConfigParser()
        self.p = ChatloggerPlugin(self.console, self.conf)

        when(self.console.config).get('b3', 'time_zone').thenReturn('GMT')
        self.p.setup_fileLogger = Mock()

    def init(self, config_content=None):
        """ load plugin config and initialise the plugin """
        if config_content:
            self.conf.loadFromString(config_content)
        else:
            if os.path.isfile(CHATLOGGER_CONFIG_FILE):
                self.conf.load(CHATLOGGER_CONFIG_FILE)
            else:
                unittest.skip("default config file '%s' does not exists" %
                              CHATLOGGER_CONFIG_FILE)
                return
        self.p.onLoadConfig()
        self.p.onStartup()

    def test_default_config(self):
        # GIVEN
        when(b3).getB3Path().thenReturn("c:\\b3_folder")
        when(b3).getConfPath().thenReturn("c:\\b3_conf_folder")
        # WHEN
        self.init()
        # THEN
        self.assertTrue(self.p._save2db)
        self.assertTrue(self.p._save2file)
        expected_log_file = 'c:\\b3_conf_folder\\chat.log' if sys.platform == 'win32' else 'c:\\b3_conf_folder/chat.log'
        self.assertEqual(expected_log_file, self.p._file_name)
        self.assertEqual("D", self.p._file_rotation_rate)
        self.assertEqual(0, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(0, self.p._hours)
        self.assertEqual(0, self.p._minutes)

    def test_empty_config(self):
        self.init("""
        """)
        self.assertTrue(self.p._save2db)
        self.assertFalse(self.p._save2file)
        self.assertIsNone(self.p._file_name)
        self.assertIsNone(self.p._file_rotation_rate)
        self.assertEqual(0, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(0, self.p._hours)
        self.assertEqual(0, self.p._minutes)

    def test_conf1(self):
        self.init(
            dedent("""
            [purge]
            max_age:7d
            hour:4
            min:0
        """))
        self.assertTrue(self.p._save2db)
        self.assertFalse(self.p._save2file)
        self.assertIsNone(self.p._file_name)
        self.assertIsNone(self.p._file_rotation_rate)
        self.assertEqual(7, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(4, self.p._hours)
        self.assertEqual(0, self.p._minutes)
class Test_mysql(B3TestCase):
    def setUp(self):
        B3TestCase.setUp(self)
        logging.getLogger('output').setLevel(logging.DEBUG)
        with logging_disabled():
            self.console.startup()
            self.conf = CfgConfigParser()
            self.p = ChatloggerPlugin(self.console, self.conf)

        ## prepare the mysql test database
        db = MySQLdb.connect(host=MYSQL_TEST_HOST, user=MYSQL_TEST_USER, passwd=MYSQL_TEST_PASSWORD)
        db.query("DROP DATABASE IF EXISTS %s" % MYSQL_TEST_DB)
        db.query("CREATE DATABASE %s CHARACTER SET utf8;" % MYSQL_TEST_DB)

        self.console.storage = DatabaseStorage(
            'mysql://%s:%s@%s/%s' % (MYSQL_TEST_USER, MYSQL_TEST_PASSWORD, MYSQL_TEST_HOST, MYSQL_TEST_DB), self.console)
        self.console.storage.executeSql("@b3/sql/b3.sql")
        self.console.storage.executeSql(CHATLOGGER_SQL_FILE)

        when(self.console.config).get('b3', 'time_zone').thenReturn('GMT')
        self.p.setup_fileLogger = Mock()

        self.conf.loadFromString(dedent("""
            [general]
            save_to_database: Yes
            save_to_file: no

            [file]
            logfile: @conf/chat.log
            rotation_rate: D

            [purge]
            max_age: 0
            hour: 0
            min: 0
        """))
        with logging_disabled():
            self.p.onLoadConfig()
            self.p.onStartup()
            self.joe = FakeClient(self.console, name="Joe", guid="joe_guid", team=TEAM_RED)
            self.simon = FakeClient(self.console, name="Simon", guid="simon_guid", team=TEAM_BLUE)
            self.joe.connects(1)
            self.simon.connects(3)

        self.assertEqual(0, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())

    def count_chatlog_lines(self):
        cursor = self.console.storage.query("select count(*) as `count` from chatlog")
        count = cursor.getValue("count")
        cursor.close()
        return count

    def count_cmdlog_lines(self):
        cursor = self.console.storage.query("select count(*) as `count` from cmdlog")
        count = cursor.getValue("count")
        cursor.close()
        return count

    def get_all_chatlog_lines_from_db(self):
        cursor = self.console.storage.query("select msg_type, client_id, client_name, client_team, msg, target_id, "
                                            "target_name, target_team from chatlog")
        lines = []
        if cursor:
            while not cursor.EOF:
                lines.append(cursor.getRow())
                cursor.moveNext()
            cursor.close()
        return lines

    def get_all_cmdlog_lines_from_db(self):
        cursor = self.console.storage.query("select admin_id, admin_name, command, data, result from cmdlog")
        lines = []
        if cursor:
            while not cursor.EOF:
                lines.append(cursor.getRow())
                cursor.moveNext()
            cursor.close()
        return lines

    def test_global_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.says("hello")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual({'client_id': 1,
                              'client_name': 'Joe',
                              'client_team': TEAM_RED,
                              'msg': 'hello',
                              'msg_type': 'ALL',
                              'target_id': None,
                              'target_name': None,
                              'target_team': None},
                             self.get_all_chatlog_lines_from_db()[0])

    def test_team_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.says2team("hi")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual({'client_id': self.joe.id,
                              'client_name': 'Joe',
                              'client_team': self.joe.team,
                              'msg': 'hi',
                              'msg_type': 'TEAM',
                              'target_id': None,
                              'target_name': None,
                              'target_team': None},
                             self.get_all_chatlog_lines_from_db()[0])

    @unittest.skipUnless(hasattr(FakeClient, "says2squad"), "FakeClient.says2squad not available in this version of B3")
    def test_squad_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.says2squad("hi")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual({'client_id': self.joe.id,
                              'client_name': 'Joe',
                              'client_team': self.joe.team,
                              'msg': 'hi',
                              'msg_type': 'SQUAD',
                              'target_id': None,
                              'target_name': None,
                              'target_team': None},
                             self.get_all_chatlog_lines_from_db()[0])

    def test_private_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.sendsPM("hi", self.simon)
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual({'client_id': self.joe.id,
                              'client_name': 'Joe',
                              'client_team': self.joe.team,
                              'msg': 'hi',
                              'msg_type': 'PM',
                              'target_id': self.simon.id,
                              'target_name': "Simon",
                              'target_team': self.simon.team},
                             self.get_all_chatlog_lines_from_db()[0])

    def test_command_gets_saved_to_db(self):
        # WHEN
        self.joe.says("!help")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())
        self.assertDictEqual({'client_id': self.joe.id,
                              'client_name': 'Joe',
                              'client_team': self.joe.team,
                              'msg': '!help',
                              'msg_type': 'ALL',
                              'target_id': None,
                              'target_name': None,
                              'target_team': None},
                             self.get_all_chatlog_lines_from_db()[0])
        self.assertDictEqual({'admin_id': 1,
                              'admin_name': 'Joe',
                              'command': 'help',
                              'data': '',
                              'result': None},
                             self.get_all_cmdlog_lines_from_db()[0])

    def test_unicode(self):
        # WHEN
        self.joe.name = u"★joe★"
        self.simon.name = u"❮❮simon❯❯"
        self.joe.sendsPM(u"hi ✪", self.simon)
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual({'client_id': self.joe.id,
                              'client_name': u"★joe★",
                              'client_team': self.joe.team,
                              'msg': u"hi ✪",
                              'msg_type': 'PM',
                              'target_id': self.simon.id,
                              'target_name': u"❮❮simon❯❯",
                              'target_team': self.simon.team},
                             self.get_all_chatlog_lines_from_db()[0])

    def test_sql_injection(self):
        # WHEN
        self.joe.says("sql injec;tion ' test")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())

        # WHEN
        self.joe.sendsPM("sql; injection ' test", self.simon)
        # THEN
        self.assertEqual(2, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())

        # WHEN
        self.joe.says("!help sql injection ' test;")
        # THEN
        self.assertEqual(3, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())

        # WHEN
        self.joe.name = "j'oe"
        self.joe.says("sql injection test2")
        # THEN
        self.assertEqual(4, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())

        # WHEN
        self.joe.name = "joe"
        self.simon.name = "s;m'n"
        self.joe.sendsPM("sql injection test2", self.simon)
        # THEN
        self.assertEqual(5, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())
Beispiel #3
0
class Test_mysql(B3TestCase):
    def setUp(self):
        B3TestCase.setUp(self)
        logging.getLogger('output').setLevel(logging.DEBUG)
        with logging_disabled():
            self.console.startup()
            self.conf = CfgConfigParser()
            self.p = ChatloggerPlugin(self.console, self.conf)

        ## prepare the mysql test database
        db = MySQLdb.connect(host=MYSQL_TEST_HOST,
                             user=MYSQL_TEST_USER,
                             passwd=MYSQL_TEST_PASSWORD)
        db.query("DROP DATABASE IF EXISTS %s" % MYSQL_TEST_DB)
        db.query("CREATE DATABASE %s CHARACTER SET utf8;" % MYSQL_TEST_DB)

        self.console.storage = DatabaseStorage(
            'mysql://%s:%s@%s/%s' % (MYSQL_TEST_USER, MYSQL_TEST_PASSWORD,
                                     MYSQL_TEST_HOST, MYSQL_TEST_DB),
            self.console)
        self.console.storage.executeSql("@b3/sql/b3.sql")
        self.console.storage.executeSql(CHATLOGGER_SQL_FILE)

        when(self.console.config).get('b3', 'time_zone').thenReturn('GMT')
        self.p.setup_fileLogger = Mock()

        self.conf.loadFromString(
            dedent("""
            [general]
            save_to_database: Yes
            save_to_file: no

            [file]
            logfile: @conf/chat.log
            rotation_rate: D

            [purge]
            max_age: 0
            hour: 0
            min: 0
        """))
        with logging_disabled():
            self.p.onLoadConfig()
            self.p.onStartup()
            self.joe = FakeClient(self.console,
                                  name="Joe",
                                  guid="joe_guid",
                                  team=TEAM_RED)
            self.simon = FakeClient(self.console,
                                    name="Simon",
                                    guid="simon_guid",
                                    team=TEAM_BLUE)
            self.joe.connects(1)
            self.simon.connects(3)

        self.assertEqual(0, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())

    def count_chatlog_lines(self):
        cursor = self.console.storage.query(
            "select count(*) as `count` from chatlog")
        count = cursor.getValue("count")
        cursor.close()
        return count

    def count_cmdlog_lines(self):
        cursor = self.console.storage.query(
            "select count(*) as `count` from cmdlog")
        count = cursor.getValue("count")
        cursor.close()
        return count

    def get_all_chatlog_lines_from_db(self):
        cursor = self.console.storage.query(
            "select msg_type, client_id, client_name, client_team, msg, target_id, "
            "target_name, target_team from chatlog")
        lines = []
        if cursor:
            while not cursor.EOF:
                lines.append(cursor.getRow())
                cursor.moveNext()
            cursor.close()
        return lines

    def get_all_cmdlog_lines_from_db(self):
        cursor = self.console.storage.query(
            "select admin_id, admin_name, command, data, result from cmdlog")
        lines = []
        if cursor:
            while not cursor.EOF:
                lines.append(cursor.getRow())
                cursor.moveNext()
            cursor.close()
        return lines

    def test_global_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.says("hello")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual(
            {
                'client_id': 1,
                'client_name': 'Joe',
                'client_team': TEAM_RED,
                'msg': 'hello',
                'msg_type': 'ALL',
                'target_id': None,
                'target_name': None,
                'target_team': None
            },
            self.get_all_chatlog_lines_from_db()[0])

    def test_team_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.says2team("hi")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual(
            {
                'client_id': self.joe.id,
                'client_name': 'Joe',
                'client_team': self.joe.team,
                'msg': 'hi',
                'msg_type': 'TEAM',
                'target_id': None,
                'target_name': None,
                'target_team': None
            },
            self.get_all_chatlog_lines_from_db()[0])

    @unittest.skipUnless(
        hasattr(FakeClient, "says2squad"),
        "FakeClient.says2squad not available in this version of B3")
    def test_squad_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.says2squad("hi")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual(
            {
                'client_id': self.joe.id,
                'client_name': 'Joe',
                'client_team': self.joe.team,
                'msg': 'hi',
                'msg_type': 'SQUAD',
                'target_id': None,
                'target_name': None,
                'target_team': None
            },
            self.get_all_chatlog_lines_from_db()[0])

    def test_private_chat_gets_saved_to_db(self):
        # WHEN
        self.joe.sendsPM("hi", self.simon)
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual(
            {
                'client_id': self.joe.id,
                'client_name': 'Joe',
                'client_team': self.joe.team,
                'msg': 'hi',
                'msg_type': 'PM',
                'target_id': self.simon.id,
                'target_name': "Simon",
                'target_team': self.simon.team
            },
            self.get_all_chatlog_lines_from_db()[0])

    def test_command_gets_saved_to_db(self):
        # WHEN
        self.joe.says("!help")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())
        self.assertDictEqual(
            {
                'client_id': self.joe.id,
                'client_name': 'Joe',
                'client_team': self.joe.team,
                'msg': '!help',
                'msg_type': 'ALL',
                'target_id': None,
                'target_name': None,
                'target_team': None
            },
            self.get_all_chatlog_lines_from_db()[0])
        self.assertDictEqual(
            {
                'admin_id': 1,
                'admin_name': 'Joe',
                'command': 'help',
                'data': '',
                'result': None
            },
            self.get_all_cmdlog_lines_from_db()[0])

    def test_unicode(self):
        # WHEN
        self.joe.name = u"★joe★"
        self.simon.name = u"❮❮simon❯❯"
        self.joe.sendsPM(u"hi ✪", self.simon)
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())
        self.assertDictEqual(
            {
                'client_id': self.joe.id,
                'client_name': u"★joe★",
                'client_team': self.joe.team,
                'msg': u"hi ✪",
                'msg_type': 'PM',
                'target_id': self.simon.id,
                'target_name': u"❮❮simon❯❯",
                'target_team': self.simon.team
            },
            self.get_all_chatlog_lines_from_db()[0])

    def test_sql_injection(self):
        # WHEN
        self.joe.says("sql injec;tion ' test")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())

        # WHEN
        self.joe.sendsPM("sql; injection ' test", self.simon)
        # THEN
        self.assertEqual(2, self.count_chatlog_lines())
        self.assertEqual(0, self.count_cmdlog_lines())

        # WHEN
        self.joe.says("!help sql injection ' test;")
        # THEN
        self.assertEqual(3, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())

        # WHEN
        self.joe.name = "j'oe"
        self.joe.says("sql injection test2")
        # THEN
        self.assertEqual(4, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())

        # WHEN
        self.joe.name = "joe"
        self.simon.name = "s;m'n"
        self.joe.sendsPM("sql injection test2", self.simon)
        # THEN
        self.assertEqual(5, self.count_chatlog_lines())
        self.assertEqual(1, self.count_cmdlog_lines())
class Test_Config(B3TestCase):
    def setUp(self):
        B3TestCase.setUp(self)
        with logging_disabled():
            self.console.startup()

        logging.getLogger('output').setLevel(logging.DEBUG)

        self.conf = CfgConfigParser()
        self.p = ChatloggerPlugin(self.console, self.conf)

        when(self.console.config).get('b3', 'time_zone').thenReturn('GMT')
        self.p.setup_fileLogger = Mock()

    def init(self, config_content=None):
        """ load plugin config and initialise the plugin """
        if config_content:
            self.conf.loadFromString(config_content)
        else:
            if os.path.isfile(CHATLOGGER_CONFIG_FILE):
                self.conf.load(CHATLOGGER_CONFIG_FILE)
            else:
                raise unittest.SkipTest("default config file '%s' does not exists" % CHATLOGGER_CONFIG_FILE)
        self.p.onLoadConfig()
        self.p.onStartup()

    def test_default_config(self):
        # GIVEN
        when(b3).getB3Path().thenReturn("c:\\b3_folder")
        when(b3).getConfPath().thenReturn("c:\\b3_conf_folder")
        # WHEN
        self.init()
        # THEN
        self.assertTrue(self.p._save2db)
        self.assertTrue(self.p._save2file)
        expected_log_file = 'c:\\b3_conf_folder\\chat.log' if sys.platform == 'win32' else 'c:\\b3_conf_folder/chat.log'
        self.assertEqual(expected_log_file, self.p._file_name)
        self.assertEqual("D", self.p._file_rotation_rate)
        self.assertEqual(0, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(0, self.p._hours)
        self.assertEqual(0, self.p._minutes)

    def test_empty_config(self):
        self.init("""
        """)
        self.assertTrue(self.p._save2db)
        self.assertFalse(self.p._save2file)
        self.assertIsNone(self.p._file_name)
        self.assertIsNone(self.p._file_rotation_rate)
        self.assertEqual(0, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(0, self.p._hours)
        self.assertEqual(0, self.p._minutes)
        self.assertEqual("chatlog", self.p._db_table)
        self.assertEqual("cmdlog", self.p._db_table_cmdlog)

    def test_conf1(self):
        self.init(dedent("""
            [purge]
            max_age:7d
            hour:4
            min:0
        """))
        self.assertTrue(self.p._save2db)
        self.assertFalse(self.p._save2file)
        self.assertIsNone(self.p._file_name)
        self.assertIsNone(self.p._file_rotation_rate)
        self.assertEqual(7, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(4, self.p._hours)
        self.assertEqual(0, self.p._minutes)

    def test_database(self):
        self.init(dedent("""
            [database]
            db_table: chatlog2
            db_table_cmdlog: cmdlog2
        """))
        self.assertEqual("chatlog2", self.p._db_table)
        self.assertEqual("cmdlog2", self.p._db_table_cmdlog)
class Test_chatlogfile(B3TestCase):
    def setUp(self):
        B3TestCase.setUp(self)
        logging.getLogger('output').setLevel(logging.DEBUG)
        with logging_disabled():
            self.console.startup()
            self.conf = CfgConfigParser()
            self.p = ChatloggerPlugin(self.console, self.conf)

        when(self.console.config).get('b3', 'time_zone').thenReturn('GMT')

        self.conf.loadFromString(dedent("""
            [general]
            save_to_database: no
            save_to_file: yes

            [file]
            logfile: @conf/chat.log
            rotation_rate: D

            [purge]
            max_age: 0
            hour: 0
            min: 0
        """))
        self.temp_conf_folder = mkdtemp(suffix="b3_conf")
        when(b3).getConfPath().thenReturn(self.temp_conf_folder)
        with logging_disabled():
            self.p.onLoadConfig()
            self.p.onStartup()

        self.chat_log_file = os.path.join(self.temp_conf_folder, 'chat.log')

        with logging_disabled():
            self.joe = FakeClient(self.console, name="Joe", guid="joe_guid", team=TEAM_RED)
            self.simon = FakeClient(self.console, name="Simon", guid="simon_guid", team=TEAM_BLUE)
            self.joe.connects(1)
            self.simon.connects(3)

    def get_all_chatlog_lines_from_logfile(self):
        lines = []
        with codecs.open(self.chat_log_file, "r", encoding="utf-8") as f:
            for l in f.readlines():
                lines.append(l.strip())
        return lines

    def count_chatlog_lines(self):
        return len(self.get_all_chatlog_lines_from_logfile())

    def assert_log_line(self, line, expected):
        """
        remove time stamp at the beginning of the line and compare the remainder
        """
        clean_line = re.sub(r"^\d+-\d+-\d+ \d\d:\d\d:\d\d\t", "", line)
        self.assertEqual(clean_line, expected)

    def test_global_chat(self):
        # WHEN
        self.joe.says("hello")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assert_log_line(self.get_all_chatlog_lines_from_logfile()[0], "@1 [Joe] to ALL:\thello")

    def test_team_chat(self):
        # WHEN
        self.joe.says2team("hello")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assert_log_line(self.get_all_chatlog_lines_from_logfile()[0], "@1 [Joe] to TEAM:\thello")

    @unittest.skipUnless(hasattr(FakeClient, "says2squad"), "FakeClient.says2squad not available in this version of B3")
    def test_squad_chat(self):
        # WHEN
        self.joe.says2squad("hi")
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assert_log_line(self.get_all_chatlog_lines_from_logfile()[0], "@1 [Joe] to SQUAD:\thi")

    def test_private_chat(self):
        # WHEN
        self.joe.sendsPM("hi", self.simon)
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assert_log_line(self.get_all_chatlog_lines_from_logfile()[0], "@1 [Joe] to PM:\thi")

    def test_unicode(self):
        # WHEN
        self.joe.name = u"★joe★"
        self.simon.name = u"❮❮simon❯❯"
        self.joe.sendsPM(u"hi ✪", self.simon)
        # THEN
        self.assertEqual(1, self.count_chatlog_lines())
        self.assert_log_line(self.get_all_chatlog_lines_from_logfile()[0], u"@1 [★joe★] to PM:\thi ✪")
class Test_Config(B3TestCase):

    def setUp(self):
        self.log = logging.getLogger('output')
        self.log.propagate = False

        B3TestCase.setUp(self)
        self.console.startup()
        self.log.propagate = True
        self.log.setLevel(logging.DEBUG)

        self.conf = XmlConfigParser()
        self.p = ChatloggerPlugin(self.console, self.conf)

        when(self.console.config).get('b3', 'time_zone').thenReturn('GMT')
        when(b3).getB3Path().thenReturn("c:\\b3_folder")
        when(b3).getConfPath().thenReturn("c:\\b3_conf_folder")
        self.p.setup_fileLogger = Mock()


    def init(self, config_content=None):
        """ load plugin config and initialise the plugin """
        if config_content:
            self.conf.loadFromString(config_content)
        else:
            if os.path.isfile(CHATLOGGER_CONFIG_FILE):
                self.conf.load(CHATLOGGER_CONFIG_FILE)
            else:
                unittest.skip("default config file '%s' does not exists" % CHATLOGGER_CONFIG_FILE)
                return
        self.p.onLoadConfig()
        self.p.onStartup()


    def test_default_config(self):
        self.init()
        self.assertTrue(self.p._save2db)
        self.assertTrue(self.p._save2file)
        expected_log_file = 'c:\\b3_conf_folder\\chat.log' if sys.platform == 'win32' else 'c:\\b3_conf_folder/chat.log'
        self.assertEqual(expected_log_file, self.p._file_name)
        self.assertEqual("D", self.p._file_rotation_rate)
        self.assertEqual(0, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(0, self.p._hours)
        self.assertEqual(0, self.p._minutes)


    def test_empty_config(self):
        self.init("""<configuration plugin="chatlogger" />""")
        self.assertTrue(self.p._save2db)
        self.assertFalse(self.p._save2file)
        self.assertIsNone(self.p._file_name)
        self.assertIsNone(self.p._file_rotation_rate)
        self.assertEqual(0, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(0, self.p._hours)
        self.assertEqual(0, self.p._minutes)


    def test_conf1(self):
        self.init("""
            <configuration plugin="chatlogger">
                <settings name="purge">
                    <set name="max_age">7d</set>
                    <set name="hour">4</set>
                    <set name="min">0</set>
                </settings>
            </configuration>
        """)
        self.assertTrue(self.p._save2db)
        self.assertFalse(self.p._save2file)
        self.assertIsNone(self.p._file_name)
        self.assertIsNone(self.p._file_rotation_rate)
        self.assertEqual(7, self.p._max_age_in_days)
        self.assertEqual(0, self.p._max_age_cmd_in_days)
        self.assertEqual(4, self.p._hours)
        self.assertEqual(0, self.p._minutes)