"""Runs integration test on the bot
"""
import os
import unittest
import re
from tgintegration import BotIntegrationClient
from karmabot.responses import START_BOT_RESPONSE, SUCCESSFUL_CLEAR_CHAT, SHOW_KARMA_NO_HISTORY_RESPONSE
from karmabot.commands_strings import START_COMMAND, CLEAR_CHAT_COMMAND, SHOW_KARMA_COMMAND, USER_INFO_COMMAND, CHAT_INFO_COMMAND, SHOW_KARMA_KEYBOARD_COMMAND


class IntegrationTests(unittest.TestCase):
    """ Runs intergation tests"""
    def setUp(self):
        """ Sets up the environment"""
        API_ID = os.environ.get("API_ID")
        API_HASH = os.environ.get("API_HASH")
        TEST_BOT_NAME = os.environ.get("TEST_BOT_NAME")
        if None in [API_HASH, API_ID, TEST_BOT_NAME]:
            print("API_ID, API_HASH, TEST_BOT_NAME not set")
            raise ValueError()

        self.TEST_BOT_NAME = TEST_BOT_NAME

        client = BotIntegrationClient(
            bot_under_test=TEST_BOT_NAME,
            session_name='./session/my_account',  # Arbitrary file path to the Pyrogram session file
            api_id=API_ID,  # See "Requirements" above, ...
            api_hash=API_HASH,  # alternatively use a `config.ini` file
            max_wait_response=15,  # Maximum timeout for bot responses
            min_wait_consecutive=2  # Minimum time to wait for consecutive messages
        )
        client.start()
        #client.clear_chat()
        self.client = client
    def tearDown(self):
        self.client.stop()
        #pass

    @unittest.skip("dont care that this works for now")
    def test_start(self):
        """ Test start command"""
        response = self.client.send_command_await(START_COMMAND, num_expected=1)
        self.assertEqual(len(response.messages), 1)
        self.assertEqual(response.messages[0].text, START_BOT_RESPONSE)

    @unittest.skip("dont care that this works for now")
    def test_showkarma_works_on_empty_chat(self):
        """Clears the chat and tests that showkarma doesn't give a response"""
        clear_chat_response = self.client.send_command_await(CLEAR_CHAT_COMMAND, num_expected=1)
        self.assertEqual(len(clear_chat_response.messages), 1)
        self.assertEqual(clear_chat_response.messages[0].text, SUCCESSFUL_CLEAR_CHAT)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        self.assertEqual(show_karma_response.messages[0].text, SHOW_KARMA_NO_HISTORY_RESPONSE)

    @unittest.skip("vote overriding broken right now")
    def test_votes_can_be_overriden(self):
        """Tests that if a message is +1 and then -1, the total net karma is 0"""
        self.client.send_command_await(CLEAR_CHAT_COMMAND, num_expected=1)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        message = show_karma_response.messages[0]
        chat_id = message.chat.id
        message_id = message.message_id
        self.client.send_message(chat_id, "+1", reply_to_message_id=message_id)

        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        bot_response = show_karma_response.messages[0].text

        bot_name_without_at = self.TEST_BOT_NAME[1:]
        does_bot_have_1_karma = bool(re.search(f"{bot_name_without_at}: 1", bot_response))
        self.assertTrue(does_bot_have_1_karma)

        self.client.send_message(chat_id, "-1", reply_to_message_id=message_id)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        does_bot_have_zero_karma = bool(re.search(f"{bot_name_without_at}: 0", show_karma_response.messages[0].text))
        self.assertTrue(does_bot_have_zero_karma, '-1 on same message should override last vote')

    @unittest.skip("TEMPORARY")
    def test_upvote(self):
        """Tests that upvoting a message results in +1 karma"""
        self.client.send_command_await(CLEAR_CHAT_COMMAND)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        message = show_karma_response.messages[0]
        chat_id = message.chat.id
        message_id = message.message_id
        self.client.send_message(chat_id, "+1", reply_to_message_id=message_id)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        bot_name_without_at = self.TEST_BOT_NAME[1:]
        bot_response = show_karma_response.messages[0].text
        does_bot_have_1_karma = re.search(f"{bot_name_without_at}: 1", bot_response)
        self.assertTrue(does_bot_have_1_karma, "Bot should have 1 karma after 1 plus 1")

    @unittest.skip("dont care that this works for now")
    def test_downvote(self):
        """Tests that downvoting a message results in -1 karma"""
        self.client.send_command_await(CLEAR_CHAT_COMMAND)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        message = show_karma_response.messages[0]
        chat_id = message.chat.id
        message_id = message.message_id
        self.client.send_message(chat_id, "-1", reply_to_message_id=message_id)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        bot_name_without_at = self.TEST_BOT_NAME[1:]
        bot_response = show_karma_response.messages[0].text
        does_bot_have_1_karma = re.search(f"{bot_name_without_at}: -1", bot_response)
        self.assertTrue(does_bot_have_1_karma, "Bot should have 1 karma after 1 plus 1")


        #(chat_id, "+1", send_to_message_id=message_id)
        #print(f"Message id: {message.message_id}")
        #TOOD: how to send message as response to other message. Could be done directly with pyrogram

        #print(clear_chat_response)
        #print(dir(clear_chat_response))
        #clear chat
        #run showkarma (capture message id)
        #make sure has empty result
        #plus 1 showkarma message
        #make sure there is a number 1 in karma
    #TODO: test keyboard implementation
    #TODO: test non existent use cases (userstats where userid doesn't exist, etc)
    #TODO: host multiple bots with swarm and split integration tests amoung them

    @unittest.skip("TEMPORARY")
    def test_userinfo(self):
        # self.client.send_command_await(CLEAR_CHAT_COMMAND)
        # show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        # self.assertEqual(len(show_karma_response.messages), 1)
        # message = show_karma_response.messages[0]
        # chat_id = message.chat.id
        # message_id = message.message_id
        # self.client.send_message(chat_id, "+1", reply_to_message_id=message_id)
        command = f"{USER_INFO_COMMAND} {self.TEST_BOT_NAME[1:]}"
        user_info_response = self.client.send_command_await(command, num_expected=1)
        self.assertEqual(len(user_info_response.messages), 1)

    @unittest.skip("TEMPORARY")
    def test_chatinfo(self):
        response = self.client.send_command_await(CHAT_INFO_COMMAND, num_expected=1)
        self.assertEqual(len(response.messages), 1)
        #TODO: check that number of users with karma is 2
        #TODO: Check total reply count

    @unittest.skip("test not yet implemented")
    def test_history_graph(self):
        #TODO: run command, check that a file asset is sent back
        #TODO: add another test case for showing a file not being sent when there is no data in the chat
        pass

    def test_check_chat_karmas(self):
        response = self.client.send_command_await(SHOW_KARMA_KEYBOARD_COMMAND, num_expected=1)
        keyboards = response.inline_keyboards
        # TODO: how to verify that there is history in another chat?
        #TODO: perhaps there should be a hidden flag to include chat with the bot
        self.assertTrue(keyboards is not None)
        self.assertTrue(len(keyboards) > 0)
        keyboard = keyboards[0]
        karma_result = keyboard.press_button_await(pattern=r'.*', num_expected=1)
        bot_name_without_at = self.TEST_BOT_NAME[1:]
        #print(karma_result)
        did_bot_provide_karma = re.search(f"{bot_name_without_at}", str(karma_result))
        self.assertTrue(did_bot_provide_karma)





if __name__ == "__main__":
    #TOOD: seperate this into test suites for the various features
    unittest.main()

"""Runs integration test on the bot
"""
import os
import unittest
import re
from tgintegration import BotIntegrationClient
from karmabot.responses import START_BOT_RESPONSE, SUCCESSFUL_CLEAR_CHAT, SHOW_KARMA_NO_HISTORY_RESPONSE
from karmabot.commands_strings import START_COMMAND, CLEAR_CHAT_COMMAND, SHOW_KARMA_COMMAND, USER_INFO_COMMAND, CHAT_INFO_COMMAND, SHOW_KARMA_KEYBOARD_COMMAND


class IntegrationTests(unittest.TestCase):
    """ Runs intergation tests"""
    def setUp(self):
        """ Sets up the environment"""
        API_ID = os.environ.get("API_ID")
        API_HASH = os.environ.get("API_HASH")
        TEST_BOT_NAME = os.environ.get("TEST_BOT_NAME")
        if None in [API_HASH, API_ID, TEST_BOT_NAME]:
            print("API_ID, API_HASH, TEST_BOT_NAME not set")
            raise ValueError()

        self.TEST_BOT_NAME = TEST_BOT_NAME

        client = BotIntegrationClient(
            bot_under_test=TEST_BOT_NAME,
            session_name='./session/my_account',  # Arbitrary file path to the Pyrogram session file
            api_id=API_ID,  # See "Requirements" above, ...
            api_hash=API_HASH,  # alternatively use a `config.ini` file
            max_wait_response=15,  # Maximum timeout for bot responses
            min_wait_consecutive=2  # Minimum time to wait for consecutive messages
        )
        client.start()
        #client.clear_chat()
        self.client = client
    def tearDown(self):
        self.client.stop()
        #pass

    @unittest.skip("dont care that this works for now")
    def test_start(self):
        """ Test start command"""
        response = self.client.send_command_await(START_COMMAND, num_expected=1)
        self.assertEqual(len(response.messages), 1)
        self.assertEqual(response.messages[0].text, START_BOT_RESPONSE)

    @unittest.skip("dont care that this works for now")
    def test_showkarma_works_on_empty_chat(self):
        """Clears the chat and tests that showkarma doesn't give a response"""
        clear_chat_response = self.client.send_command_await(CLEAR_CHAT_COMMAND, num_expected=1)
        self.assertEqual(len(clear_chat_response.messages), 1)
        self.assertEqual(clear_chat_response.messages[0].text, SUCCESSFUL_CLEAR_CHAT)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        self.assertEqual(show_karma_response.messages[0].text, SHOW_KARMA_NO_HISTORY_RESPONSE)

    @unittest.skip("vote overriding broken right now")
    def test_votes_can_be_overriden(self):
        """Tests that if a message is +1 and then -1, the total net karma is 0"""
        self.client.send_command_await(CLEAR_CHAT_COMMAND, num_expected=1)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        message = show_karma_response.messages[0]
        chat_id = message.chat.id
        message_id = message.message_id
        self.client.send_message(chat_id, "+1", reply_to_message_id=message_id)

        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        bot_response = show_karma_response.messages[0].text

        bot_name_without_at = self.TEST_BOT_NAME[1:]
        does_bot_have_1_karma = bool(re.search(f"{bot_name_without_at}: 1", bot_response))
        self.assertTrue(does_bot_have_1_karma)

        self.client.send_message(chat_id, "-1", reply_to_message_id=message_id)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        does_bot_have_zero_karma = bool(re.search(f"{bot_name_without_at}: 0", show_karma_response.messages[0].text))
        self.assertTrue(does_bot_have_zero_karma, '-1 on same message should override last vote')

    @unittest.skip("TEMPORARY")
    def test_upvote(self):
        """Tests that upvoting a message results in +1 karma"""
        self.client.send_command_await(CLEAR_CHAT_COMMAND)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        message = show_karma_response.messages[0]
        chat_id = message.chat.id
        message_id = message.message_id
        self.client.send_message(chat_id, "+1", reply_to_message_id=message_id)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        bot_name_without_at = self.TEST_BOT_NAME[1:]
        bot_response = show_karma_response.messages[0].text
        does_bot_have_1_karma = re.search(f"{bot_name_without_at}: 1", bot_response)
        self.assertTrue(does_bot_have_1_karma, "Bot should have 1 karma after 1 plus 1")

    @unittest.skip("dont care that this works for now")
    def test_downvote(self):
        """Tests that downvoting a message results in -1 karma"""
        self.client.send_command_await(CLEAR_CHAT_COMMAND)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)
        message = show_karma_response.messages[0]
        chat_id = message.chat.id
        message_id = message.message_id
        self.client.send_message(chat_id, "-1", reply_to_message_id=message_id)
        show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        self.assertEqual(len(show_karma_response.messages), 1)

        bot_name_without_at = self.TEST_BOT_NAME[1:]
        bot_response = show_karma_response.messages[0].text
        does_bot_have_1_karma = re.search(f"{bot_name_without_at}: -1", bot_response)
        self.assertTrue(does_bot_have_1_karma, "Bot should have 1 karma after 1 plus 1")


        #(chat_id, "+1", send_to_message_id=message_id)
        #print(f"Message id: {message.message_id}")
        #TOOD: how to send message as response to other message. Could be done directly with pyrogram

        #print(clear_chat_response)
        #print(dir(clear_chat_response))
        #clear chat
        #run showkarma (capture message id)
        #make sure has empty result
        #plus 1 showkarma message
        #make sure there is a number 1 in karma
    #TODO: test keyboard implementation
    #TODO: test non existent use cases (userstats where userid doesn't exist, etc)
    #TODO: host multiple bots with swarm and split integration tests amoung them

    @unittest.skip("TEMPORARY")
    def test_userinfo(self):
        # self.client.send_command_await(CLEAR_CHAT_COMMAND)
        # show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1)
        # self.assertEqual(len(show_karma_response.messages), 1)
        # message = show_karma_response.messages[0]
        # chat_id = message.chat.id
        # message_id = message.message_id
        # self.client.send_message(chat_id, "+1", reply_to_message_id=message_id)
        command = f"{USER_INFO_COMMAND} {self.TEST_BOT_NAME[1:]}"
        user_info_response = self.client.send_command_await(command, num_expected=1)
        self.assertEqual(len(user_info_response.messages), 1)

    @unittest.skip("TEMPORARY")
    def test_chatinfo(self):
        response = self.client.send_command_await(CHAT_INFO_COMMAND, num_expected=1)
        self.assertEqual(len(response.messages), 1)
        #TODO: check that number of users with karma is 2
        #TODO: Check total reply count

    @unittest.skip("test not yet implemented")
    def test_history_graph(self):
        #TODO: run command, check that a file asset is sent back
        #TODO: add another test case for showing a file not being sent when there is no data in the chat
        pass

    def test_check_chat_karmas(self):
        response = self.client.send_command_await(SHOW_KARMA_KEYBOARD_COMMAND, num_expected=1)
        keyboards = response.inline_keyboards
        # TODO: how to verify that there is history in another chat?
        #TODO: perhaps there should be a hidden flag to include chat with the bot
        self.assertTrue(keyboards is not None)
        self.assertTrue(len(keyboards) > 0)
        keyboard = keyboards[0]
        karma_result = keyboard.press_button_await(pattern=r'.*', num_expected=1)
        bot_name_without_at = self.TEST_BOT_NAME[1:]
        #print(karma_result)
        did_bot_provide_karma = re.search(f"{bot_name_without_at}", str(karma_result))
        self.assertTrue(did_bot_provide_karma)





if __name__ == "__main__":
    #TOOD: seperate this into test suites for the various features
    unittest.main()

Runs integration test on the bot Runs intergation tests Sets up the environment # Arbitrary file path to the Pyrogram session file # See "Requirements" above, ... # alternatively use a `config.ini` file # Maximum timeout for bot responses # Minimum time to wait for consecutive messages #client.clear_chat() #pass Test start command Clears the chat and tests that showkarma doesn't give a response Tests that if a message is +1 and then -1, the total net karma is 0 Tests that upvoting a message results in +1 karma Tests that downvoting a message results in -1 karma #(chat_id, "+1", send_to_message_id=message_id) #print(f"Message id: {message.message_id}") #TOOD: how to send message as response to other message. Could be done directly with pyrogram #print(clear_chat_response) #print(dir(clear_chat_response)) #clear chat #run showkarma (capture message id) #make sure has empty result #plus 1 showkarma message #make sure there is a number 1 in karma #TODO: test keyboard implementation #TODO: test non existent use cases (userstats where userid doesn't exist, etc) #TODO: host multiple bots with swarm and split integration tests amoung them # self.client.send_command_await(CLEAR_CHAT_COMMAND) # show_karma_response = self.client.send_command_await(SHOW_KARMA_COMMAND, num_expected=1) # self.assertEqual(len(show_karma_response.messages), 1) # message = show_karma_response.messages[0] # chat_id = message.chat.id # message_id = message.message_id # self.client.send_message(chat_id, "+1", reply_to_message_id=message_id) #TODO: check that number of users with karma is 2 #TODO: Check total reply count #TODO: run command, check that a file asset is sent back #TODO: add another test case for showing a file not being sent when there is no data in the chat # TODO: how to verify that there is history in another chat? #TODO: perhaps there should be a hidden flag to include chat with the bot #print(karma_result) #TOOD: seperate this into test suites for the various features