Example #1
0
async def test_block_commands(controller: BotController):
    # - create block, list blocks, remove block, list blocks
    async with controller.collect(count=1) as response:
        await controller.send_command("add_blocklisted_tag", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Added tag to blocklist: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "Current blocklist for this chat:" in lines
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_blocklisted_tags")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current blocklist for this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("remove_blocklisted_tag", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Removed tag from blocklist: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "Current blocklist for this chat:" in lines
    assert "- test" not in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_blocklisted_tags")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current blocklist for this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines
Example #2
0
async def test_neaten_link_in_button_with_image(controller: BotController,
                                                bot: FASearchBot):
    # Creating an example message to forward to the bot
    client_user = await controller.client.get_me()
    user_id = client_user.id
    async with controller.collect(count=1) as test_msg:
        requests.post(
            f"https://api.telegram.org/bot{bot.bot_key}/sendPhoto",
            json={
                "chat_id": user_id,
                "photo":
                "https://t.furaffinity.net/[email protected]",
                "reply_markup": {
                    "inline_keyboard": [[{
                        "text":
                        "View on FA",
                        "url":
                        "https://www.furaffinity.net/view/19925704/"
                    }]]
                }
            })
    msg_id = test_msg.messages[0].message_id

    # Run the test
    async with controller.collect(count=2) as response:
        await controller.client.forward_messages(controller.peer_id,
                                                 controller.peer_id, msg_id)

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "19925704" in response.messages[-1].caption
    assert response.messages[-1].photo
Example #3
0
async def test_group_migration(controller: BotController, group_chat: Chat):
    # Create subscription
    async with controller.collect(count=1, peer=group_chat.id) as response:
        await controller.send_command("add_subscription", ["test"],
                                      peer=group_chat.id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Added subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert len(lines) >= 3
    assert "Current subscriptions in this chat:" in lines
    assert "- test" in lines

    # List subscriptions
    async with controller.collect(count=1, peer=group_chat.id) as response:
        await controller.send_command("list_subscriptions", peer=group_chat.id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    # Migrate chat to supergroup
    updates = await controller.client.send(
        MigrateChat(chat_id=abs(group_chat.id)))
    new_chat_id = int(
        f"-100{[chat.id for chat in updates.chats if chat.id != abs(group_chat.id)][0]}"
    )
    group_chat.id = new_chat_id

    # List subscriptions
    async with controller.collect(count=1, peer=new_chat_id) as response:
        await controller.send_command("list_subscriptions", peer=new_chat_id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    # Delete subscription
    async with controller.collect(count=1, peer=new_chat_id) as response:
        await controller.send_command("remove_subscription", ["test"],
                                      peer=new_chat_id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Removed subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines

    # List subscriptions
    async with controller.collect(count=1, peer=new_chat_id) as response:
        await controller.send_command("list_subscriptions", peer=new_chat_id)
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines
async def test_start(controller: BotController):
    # - Get start message
    async with controller.collect(count=1) as response:
        await controller.send_command("/start")

    assert response.num_messages == 1
    assert "@deerspangle" in response.messages[0].text
Example #5
0
async def test_commands(controller: BotController):
    # The BotController automatically loads the available commands and we test them all here
    for c in controller.command_list:
        async with controller.collect() as res:  # type: Response
            await controller.send_command(c.command)
        assert not res.is_empty, "Bot did not respond to command /{}.".format(
            c.command)
Example #6
0
async def test_neaten_link(controller: BotController):
    # - send link, get neatened pic
    async with controller.collect(count=2) as response:
        await controller.client.send_message(
            controller.peer_id, "https://www.furaffinity.net/view/19925704/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "19925704" in response.messages[-1].caption
    assert response.messages[-1].photo
Example #7
0
async def run_example(client: Client):
    controller = BotController(
        peer="@StatInfoTestBot",
        client=client,
        max_wait=8,  # Maximum timeout for responses (optional)
        wait_consecutive=
        2,  # Minimum time to wait for more/consecutive messages (optional)
        raise_no_response=
        True,  # Raise `InvalidResponseError` when no response received (defaults to True)
        global_action_delay=
        2.5,  # Choosing a rather high delay so we can follow along in realtime (optional)
    )

    # expecting 2 messages in reply for /start command
    async with controller.collect(count=2) as response:  # type: Response
        await controller.send_command("start")

    assert response.num_messages == 2

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("help")

    assert response.num_messages == 1
    assert "The following commands are available" in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("statistics")

    assert response.num_messages == 1

    # expecting to get statistics for today
    current_date = str(date.today())
    assert current_date in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("country")

    assert response.num_messages == 1
    assert "Please, enter country name." in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await client.send_message(controller.peer_id, "Russian Federation")

    assert response.num_messages == 1
    assert "Russian Federation" in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("contacts")

    assert response.num_messages == 1
    assert "4 members" in response.full_text

    async with controller.collect(count=1) as response:  # type: Response
        await client.send_message(controller.peer_id, "hi")

    assert response.num_messages == 1
    assert "To get to know me better" in response.full_text
Example #8
0
async def test_no_neaten_caption_in_group(controller: BotController,
                                          group_chat: Chat):
    # - in group neaten doesn't reply to image with caption link
    group_id = group_chat.id
    thumb_link = "https://t.furaffinity.net/[email protected]"
    async with controller.collect(peer=group_id, raise_=False) as response:
        await controller.client.send_photo(
            group_id,
            thumb_link,
            caption="https://www.furaffinity.net/view/19925704/")

    assert response.num_messages == 0
Example #9
0
async def test_neaten_link_in_group(controller: BotController,
                                    group_chat: Chat):
    # - neaten link in group
    group_id = group_chat.id
    async with controller.collect(count=2, peer=group_id) as response:
        await controller.client.send_message(
            group_id, "https://www.furaffinity.net/view/19925704/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "19925704" in response.messages[-1].caption
    assert response.messages[-1].photo
Example #10
0
async def test_neaten_pdf_link(controller: BotController):
    # - send link, get neatened pic
    async with controller.collect(count=2) as response:
        await controller.client.send_message(
            controller.peer_id, "https://www.furaffinity.net/view/41734655/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert "41734655" in response.messages[-1].caption
    assert "Jaystoat" in response.messages[-1].caption
    assert "Lights In The Sky" in response.messages[-1].caption
    assert response.messages[-1].document
Example #11
0
async def test_run_example(controller: BotController, client):
    await controller.clear_chat()

    async with controller.collect(count=1) as response:  # type: Response
        await controller.send_command("start")

    assert response.num_messages == 1

    async with controller.collect(count=1) as response:  # type: Response
        await client.send_message(controller.peer_id, "1")

    assert response.num_messages == 1

    inline_keyboard = response.reply_keyboard

    async with controller.collect(count=1) as response:  # type: Response
        await inline_keyboard.click(pattern="1")

    assert response.num_messages == 1

    async with controller.collect(count=2) as response:  # type: Response
        await client.send_message(controller.peer_id, "Wrong message")

    assert response.num_messages == 2
    assert "Введите число с клавиатуры" in response.full_text

    while r"Ваш результат" not in response.full_text:
        async with controller.collect(count=1) as response:  # type: Response
            await inline_keyboard.click(pattern="1")

    async with controller.collect(count=1) as response:  # type: Response
        await inline_keyboard.click(pattern="1")

    assert "Вы также можете создать свой собственный тест по команде /create" \
           in response.full_text
async def test_neaten_gif(controller: BotController):
    # - send link, make pretty gif
    submission_id = "27408045"
    # Delete cache
    filename = f"{FASubmission.GIF_CACHE_DIR}/{submission_id}.mp4"
    if os.path.exists(filename):
        os.remove(filename)

    # Send neaten command
    async with controller.collect(count=2, max_wait=300) as response:
        await controller.client.send_message(
            controller.peer_id,
            f"https://www.furaffinity.net/view/{submission_id}/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert submission_id in response.messages[-1].caption
    assert response.messages[-1].animation
async def test_neaten_gif_from_cache(controller: BotController,
                                     bot: FASearchBot):
    # - send link, get pretty gif from cache
    submission_id = "27408045"
    # Populate cache
    submission = await bot.api.get_full_submission(submission_id)
    filename = submission._get_gif_from_cache()
    if filename is None:
        output_path = await submission._convert_gif(submission.download_url)
        submission._save_gif_to_cache(output_path)

    async with controller.collect(count=2) as response:
        await controller.client.send_message(
            controller.peer_id, "https://www.furaffinity.net/view/27408045/")

    assert response.num_messages == 2
    assert response.messages[0].text.startswith("⏳")
    assert submission_id in response.messages[-1].caption
    assert response.messages[-1].animation
Example #14
0
async def test_explore_button(controller: BotController):
    # Send /start to peer_user and wait for 3 messages
    async with controller.collect(count=3) as start:
        await controller.send_command("/start")

    # Click the "Explore" keyboard button
    explore = await start.reply_keyboard.click(pattern=r".*Explore")

    assert not explore.is_empty, 'Pressing the "Explore" button had no effect.'
    assert explore.inline_keyboards, 'The "Explore" message had no inline keyboard.'

    # Click the "Explore" inline keyboard button 10 times or until it says that
    # all bots have been explored
    count = 10
    while "explored all the bots" not in explore.full_text:
        if count == 0:
            break  # ok

        # Pressing an inline button also makes the BotController listen for edit events.
        explore = await explore.inline_keyboards[0].click(index=2)
        assert not explore.is_empty, 'Pressing the "Explore" button had no effect.'
        count -= 1
Example #15
0
async def run_example(client: Client):
    controller = BotController(
        peer=
        "@BotListBot",  # We are going to run tests on https://t.me/BotListBot
        client=client,
        max_wait=8,  # Maximum timeout for responses (optional)
        wait_consecutive=
        2,  # Minimum time to wait for more/consecutive messages (optional)
        raise_no_response=
        True,  # Raise `InvalidResponseError` when no response received (defaults to True)
        global_action_delay=
        2.5,  # Choosing a rather high delay so we can follow along in realtime (optional)
    )

    print("Clearing chat to start with a blank screen...")
    await controller.clear_chat()

    print("Sending /start and waiting for exactly 3 messages...")
    async with controller.collect(count=3) as response:  # type: Response
        await controller.send_command("start")

    assert response.num_messages == 3
    print("Three messages received, bundled as a `Response`.")
    assert response.messages[0].sticker
    print("First message is a sticker.")

    print("Let's examine the buttons in the response...")
    inline_keyboard = response.inline_keyboards[0]
    assert len(inline_keyboard.rows[0]) == 3
    print("Yep, there are three buttons in the first row.")

    # We can also press the inline keyboard buttons, in this case based on a pattern:
    print("Clicking the button matching the regex r'.*Examples'")
    examples = await inline_keyboard.click(pattern=r".*Examples")

    assert "Examples for contributing to the BotList" in examples.full_text
    # As the bot edits the message, `.click()` automatically listens for "message edited"
    # updates and returns the new state as `Response`.

    print(
        "So what happens when we send an invalid query or the peer fails to respond?"
    )
    from tgintegration import InvalidResponseError

    try:
        # The following instruction will raise an `InvalidResponseError` after
        # `controller.max_wait` seconds. This is because we passed `raise_no_response=True`
        # during controller initialization.
        print("Expecting unhandled command to raise InvalidResponseError...")
        async with controller.collect():
            await controller.send_command("ayylmao")
    except InvalidResponseError:
        print("Ok, raised as expected.")

    # If `raise_` is explicitly set to False, no exception is raised
    async with controller.collect(raise_=False) as response:  # type: Response
        print("Sending a message but expecting no reply...")
        await client.send_message(controller.peer_id, "Henlo Fren")

    # In this case, tgintegration will simply emit a warning, but you can still assert
    # that no response has been received by using the `is_empty` property.
    assert response.is_empty

    print("Success!")
Example #16
0
async def test_subscription_commands(controller: BotController):
    # - create subscription, list subscriptions, remove subscription, list subscriptions

    async with controller.collect(count=1) as response:
        await controller.send_command("add_subscription", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Added subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert len(lines) >= 3
    assert "Current subscriptions in this chat:" in lines
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("pause", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Paused subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- ⏸<s>test</s>" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- ⏸<s>test</s>" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("resume", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Resumed subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("remove_subscription", ["test"])
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Removed subscription: \"test\".")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines

    async with controller.collect(count=1) as response:
        await controller.send_command("list_subscriptions")
    assert response.num_messages == 1
    assert response.messages[0].text.startswith(
        "Current subscriptions in this chat:")
    lines = response.messages[0].text.html.split("\n")
    assert "- test" not in lines
Example #17
0
async def perform_full_run(controller: BotController, max_upgrades_per_type: int = 5):
    # Setup
    await controller.clear_chat()
    await asyncio.sleep(2)

    async def restart() -> Response:
        async with controller.collect(f.text) as start:
            await controller.send_command("restart", add_bot_name=False)
        return start

    # Extract keyboard buttons of /start response
    main_menu = get_buttons(await restart())

    async def click_button(menu: Dict[str, str], key: str) -> Dict[str, str]:
        async with controller.collect() as response:  # type: Response
            await controller.client.send_message(controller.peer_id, menu[key])

        return get_buttons(response)

    # Get World Exp if possible
    if "worldexp" in main_menu:
        worldexp_menu = await click_button(main_menu, "worldexp")
        confirm_menu = await click_button(worldexp_menu, "claimx1")
        await click_button(confirm_menu, "yes")

    # Construct buildings
    build_menu = await click_button(main_menu, "buildings")

    for building in ["lumbermill", "goldmine", "armory", "smithy"]:
        num_upgraded = 0
        while num_upgraded < max_upgrades_per_type:
            async with controller.collect() as build_response:
                await controller.client.send_message(
                    controller.peer_id, build_menu[building]
                )

            if "you don't have enough" in build_response.full_text.lower():
                break
            num_upgraded += 1

    # Upgrade Hero Equipment
    hero_menu = await click_button(main_menu, "hero")
    equip_menu = await click_button(hero_menu, "equipment")

    # For every possible equipment, upgrade it until there are not enough resources left
    for equip_button in (k for k in equip_menu.keys() if k.startswith("up")):
        num_upgraded = 0
        while num_upgraded < max_upgrades_per_type:
            async with controller.collect() as upgrade_response:
                await controller.client.send_message(
                    controller.peer_id, equip_menu[equip_button]
                )
            if "you don't have enough" in upgrade_response.full_text.lower():
                break
            num_upgraded += 1

    # Attack Player
    battle_menu = await click_button(main_menu, "battle")
    arena_menu = await click_button(battle_menu, "arena")
    normal_match_menu = await click_button(arena_menu, "normalmatch")

    if "fight" in normal_match_menu:
        await click_button(normal_match_menu, "fight")

    # Attack Boss
    bosses_menu = await click_button(battle_menu, "bosses")
    if "attackmax" in bosses_menu:
        await click_button(bosses_menu, "attackmax")