Пример #1
0
def test_error_handler(caplog: _pytest.logging.caplog,
                       mocker: pytest_mock.mocker) -> None:
    """
    Tests error handler method.

    Args:
        caplog: Fixture for log messages capturing.
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker, reader=False)
    bot = Bot(token='FAKE_TOKEN', username='******')

    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, context.bot.send_message = get_kwargs_grabber()
    getattr(bot, '_error')(update, context)

    assert len(caplog.records) == 1
    record: logging.LogRecord = caplog.records[0]
    assert record.levelno == logging.WARNING
    assert 'caused error' in record.message

    assert len(parameters) == 1
    assert 'internal error' in parameters[0]['text']
Пример #2
0
def test_boolean_question() -> None:
    """Tests the request for a boolean value to the user."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.callback_query.edit_message_text = get_kwargs_grabber()
    assert getattr(BotConfig, '_boolean_question')(
        update,
        context,
        'fake_text',
        'fake_variable',
        fake_handler
    ) == BotConfig.BOOLEAN_INPUT
    assert parameters[0]['text'] == 'fake_text'
    assert parameters[0]['reply_markup'].to_dict() == {
        'inline_keyboard': [
            [
                {
                    'text': 'Enable',
                    'callback_data': str(BotConfig.ENABLE)
                },
                {
                    'text': 'Disable',
                    'callback_data': str(BotConfig.DISABLE)
                }
            ]
        ]
    }
    assert context.user_data == {
        BotConfig.CURRENT_VARIABLE: 'fake_variable',
        BotConfig.RETURN_HANDLER: fake_handler
    }
    assert update.callback_query.answered
Пример #3
0
def test_surveillance_errors(mocker: pytest_mock.mocker) -> None:
    """
    Tests errors in "start" command invocation.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker)
    threads = mock_run_async(mocker)
    bot = Bot(token='FAKE_TOKEN', username='******')
    bot.camera.start()
    sleep(0.1)  # Wait for fps calculation

    update = get_mocked_update_object()
    context = get_mocked_context_object()

    action_params, context.bot.send_chat_action = get_kwargs_grabber()
    parameters, update.message.reply_text = get_kwargs_grabber()

    bot.updater.dispatcher.commands['surveillance_stop'](update, context)
    bot.updater.dispatcher.commands['surveillance_start'](update, context)
    while not bot.camera.is_surveillance_active:
        pass
    bot.updater.dispatcher.commands['surveillance_start'](update, context)
    while len(action_params) < 1:
        pass
    bot.updater.dispatcher.commands['surveillance_stop'](update, context)

    threads[0].join()
    assert 'not started' in parameters[0]['text']
    assert 'already started' in parameters[2]['text']
    bot.camera.stop()
Пример #4
0
def test_get_video_command(mocker: pytest_mock.mocker) -> None:
    """
    Tests "get_video" command invocation.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker)
    bot = Bot(token='FAKE_TOKEN', username='******')
    bot.camera.start()
    sleep(0.2)  # Wait for fps calculation

    update = get_mocked_update_object()
    context = get_mocked_context_object()
    context.bot_data['od_video_duration'] = 0.1

    action_params, context.bot.send_chat_action = get_kwargs_grabber()
    video_params, context.bot.send_video = get_kwargs_grabber()

    bot.updater.dispatcher.commands['get_video'](update, context)
    assert action_params[0]['action'] == 'record_video'
    assert action_params[1]['action'] == 'upload_video'
    assert video_params[0]['video'].read(12) == b'\x00\x00\x00\x1cftypisom'
    bot.camera.stop()
Пример #5
0
def test_integer_input() -> None:
    """Tests the store of an integer value received from the user."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    context.user_data[BotConfig.CURRENT_VARIABLE] = 'fake_variable'
    context.user_data[BotConfig.RETURN_HANDLER] = fake_handler

    context.bot_data['fake_variable'] = 24
    update.message.text = '42'

    assert getattr(BotConfig, '_integer_input')(
        update,
        context
    ) == 'fake_return'
    assert context.bot_data['fake_variable'] == 42

    # Invalid values
    params, update.message.reply_text = get_kwargs_grabber()
    for value in ('-1', '101', 'BAD_TYPE'):
        update.message.text = value
        assert getattr(BotConfig, '_integer_input')(
            update,
            context
        ) == BotConfig.INTEGER_INPUT
        assert 'Invalid value' in params.pop()['text']
Пример #6
0
def test_start_command(mocker: pytest_mock.mocker) -> None:
    """
    Tests "start" command invocation.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker, reader=False)
    bot = Bot(token='FAKE_TOKEN', username='******')

    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.message.reply_text = get_kwargs_grabber()
    bot.updater.dispatcher.commands['start'](update, context)
    assert len(parameters) == 2

    # Welcome message
    assert 'Welcome' in parameters[0]['text']

    # Help message
    assert 'available commands:' in parameters[1]['text']

    # Reply keyboard
    assert parameters[1]['reply_markup']['keyboard'] == [[
        '/get_photo', '/get_video'
    ], ['/surveillance_start']]
Пример #7
0
def test_command_wrapper(caplog: _pytest.logging.caplog,
                         mocker: pytest_mock.mocker) -> None:
    """
    Tests bot commands wrapping.

    Args:
        caplog: Fixture for log messages capturing.
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker, reader=False)
    bot = Bot(token='FAKE_TOKEN', username='******')

    update = get_mocked_update_object()
    context = get_mocked_context_object()

    # Checks default configuration
    bot.updater.dispatcher.commands['start'](update, context)
    assert len(context.bot_data) == 5

    # Unauthorized
    update.effective_chat.username = '******'
    bot.updater.dispatcher.commands['start'](update, context)
    assert len(caplog.records) == 1
    record: logging.LogRecord = caplog.records[0]
    assert record.levelno == logging.WARNING
    assert 'Unauthorized' in record.message
Пример #8
0
def test_change_od_video_duration() -> None:
    """Tests on demand video duration changing action."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.callback_query.edit_message_text = get_kwargs_grabber()
    BotConfig.ensure_defaults(context)
    getattr(BotConfig, '_change_od_video_duration')(update, context)
    assert '*On Demand video duration*' in parameters[0]['text']
Пример #9
0
def test_change_srv_picture_interval() -> None:
    """Tests surveillance picture interval changing action."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.callback_query.edit_message_text = get_kwargs_grabber()
    BotConfig.ensure_defaults(context)
    getattr(BotConfig, '_change_srv_picture_interval')(update, context)
    assert '*Surveillance picture interval*' in parameters[0]['text']
Пример #10
0
def test_change_motion_contours() -> None:
    """Tests motion contours changing action."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.callback_query.edit_message_text = get_kwargs_grabber()
    BotConfig.ensure_defaults(context)
    getattr(BotConfig, '_change_motion_contours')(update, context)
    assert '*Motion contours*' in parameters[0]['text']
Пример #11
0
def test_boolean_input() -> None:
    """Tests the store of a boolean value received from the user."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    context.user_data[BotConfig.CURRENT_VARIABLE] = 'fake_variable'
    context.user_data[BotConfig.RETURN_HANDLER] = fake_handler

    context.bot_data['fake_variable'] = False
    update.callback_query.data = BotConfig.ENABLE

    assert getattr(BotConfig, '_boolean_input')(
        update,
        context
    ) == 'fake_return'
    assert context.bot_data['fake_variable'] is True
Пример #12
0
def test_main_menu() -> None:
    """Tests main menu generation."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.message.reply_text = get_kwargs_grabber()
    assert getattr(BotConfig, '_main_menu')(
        update,
        context
    ) == BotConfig.MAIN_MENU
    assert '*Surveillance Telegram Bot Configuration*' in parameters[0]['text']
    assert parameters[0]['reply_markup'].to_dict() == {
        'inline_keyboard': [
            [
                {
                    'text': 'General configuration',
                    'callback_data': str(BotConfig.GENERAL_CONFIG)
                }
            ],
            [
                {
                    'text': 'Surveillance mode configuration',
                    'callback_data': str(BotConfig.SURVEILLANCE_CONFIG)
                }
            ],
            [
                {
                    'text': 'Done',
                    'callback_data': str(BotConfig.END)
                }
            ]
        ]
    }

    # Answering a callback query instead of replying message
    update.message = None
    parameters2, update.callback_query.edit_message_text = get_kwargs_grabber()
    assert getattr(BotConfig, '_main_menu')(
        update,
        context
    ) == BotConfig.MAIN_MENU
    assert parameters == parameters2
    assert update.callback_query.answered
Пример #13
0
def test_end() -> None:
    """Tests the end configuration process method."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    context.user_data['key'] = 'value'

    # Done
    parameters, update.callback_query.edit_message_text = get_kwargs_grabber()
    assert getattr(BotConfig, '_end')(update, context) == BotConfig.END
    assert parameters[0]['text'] == 'Configuration done.'
    assert len(context.user_data) == 0
    assert update.callback_query.answered

    # Cancel
    update.callback_query = None
    parameters, update.message.reply_text = get_kwargs_grabber()
    assert getattr(BotConfig, '_end')(update, context) == BotConfig.END
    assert parameters[0]['text'] == 'Configuration canceled.'
Пример #14
0
def test_integer_question() -> None:
    """Tests the request for an integer value to the user."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.callback_query.edit_message_text = get_kwargs_grabber()
    assert getattr(BotConfig, '_integer_question')(
        update,
        context,
        'fake_text',
        'fake_variable',
        fake_handler
    ) == BotConfig.INTEGER_INPUT
    assert parameters[0]['text'] == 'fake_text'
    assert context.user_data == {
        BotConfig.CURRENT_VARIABLE: 'fake_variable',
        BotConfig.RETURN_HANDLER: fake_handler
    }
    assert update.callback_query.answered
Пример #15
0
def test_surveillance_start_command(mocker: pytest_mock.mocker) -> None:
    """
    Tests "surveillance_start" command invocation.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker)
    threads = mock_run_async(mocker)
    bot = Bot(token='FAKE_TOKEN', username='******')
    bot.camera.start()
    sleep(0.2)  # Wait for fps calculation

    update = get_mocked_update_object()
    context = get_mocked_context_object()
    context.bot_data['srv_video_duration'] = 0.3
    context.bot_data['srv_picture_interval'] = 0.2

    action_params, context.bot.send_chat_action = get_kwargs_grabber()
    parameters, update.message.reply_text = get_kwargs_grabber()

    bot.updater.dispatcher.commands['surveillance_status'](update, context)
    bot.updater.dispatcher.commands['surveillance_start'](update, context)
    while not bot.camera.is_surveillance_active:
        pass
    bot.updater.dispatcher.commands['surveillance_status'](update, context)
    while len(action_params) < 4:
        pass
    bot.updater.dispatcher.commands['surveillance_stop'](update, context)

    threads[0].join()
    assert 'not active' in parameters[0]['text']
    assert 'started' in parameters[1]['text']
    assert 'is active' in parameters[2]['text']
    assert 'DETECTED' in parameters[3]['text']
    assert 'Recording' in parameters[4]['text']

    assert action_params[0]['action'] == 'record_video'
    assert action_params[1]['action'] == 'upload_photo'
    assert action_params[2]['action'] == 'record_video'
    assert action_params[3]['action'] == 'upload_video'
    bot.camera.stop()
Пример #16
0
def test_surveillance_config() -> None:
    """Tests surveillance config menu generation."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.message.reply_text = get_kwargs_grabber()
    BotConfig.ensure_defaults(context)
    assert getattr(BotConfig, '_surveillance_config')(
        update,
        context
    ) == BotConfig.SURVEILLANCE_CONFIG
    assert '*Surveillance Mode configuration*' in parameters[0]['text']
    assert parameters[0]['reply_markup'].to_dict() == {
        'inline_keyboard': [
            [
                {
                    'text': 'Video duration',
                    'callback_data': str(BotConfig.CHANGE_SRV_VIDEO_DURATION)
                }
            ],
            [
                {
                    'text': 'Picture Interval',
                    'callback_data': str(BotConfig.CHANGE_SRV_PICTURE_INTERVAL)
                }
            ],
            [
                {
                    'text': 'Draw motion contours',
                    'callback_data': str(BotConfig.CHANGE_SRV_MOTION_CONTOURS)
                }
            ],
            [
                {
                    'text': 'Back',
                    'callback_data': str(BotConfig.END)
                }
            ]
        ]
    }
Пример #17
0
def test_get_photo_command(mocker: pytest_mock.mocker) -> None:
    """
    Tests "get_photo" command invocation.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker)
    bot = Bot(token='FAKE_TOKEN', username='******')
    bot.camera.start()

    update = get_mocked_update_object()
    context = get_mocked_context_object()
    context.bot_data['timestamp'] = False

    action_params, context.bot.send_chat_action = get_kwargs_grabber()
    photo_params, context.bot.send_photo = get_kwargs_grabber()

    bot.updater.dispatcher.commands['get_photo'](update, context)
    assert action_params[0]['action'] == 'upload_photo'
    assert md5(photo_params[0]['photo'].read()).hexdigest() in FRAMES_MD5
    bot.camera.stop()
Пример #18
0
def test_general_config() -> None:
    """Tests general config menu generation."""
    update = get_mocked_update_object()
    context = get_mocked_context_object()

    parameters, update.message.reply_text = get_kwargs_grabber()
    BotConfig.ensure_defaults(context)
    assert getattr(BotConfig, '_general_config')(
        update,
        context
    ) == BotConfig.GENERAL_CONFIG
    assert '*General configuration*' in parameters[0]['text']
    assert parameters[0]['reply_markup'].to_dict() == {
        'inline_keyboard':
            [
                [
                    {
                        'text': 'Timestamp',
                        'callback_data': str(BotConfig.CHANGE_TIMESTAMP)
                    }
                ],
                [
                    {
                        'text': 'On Demand video duration',
                        'callback_data': str(
                            BotConfig.CHANGE_OD_VIDEO_DURATION
                        )
                    }
                ],
                [
                    {
                        'text': 'Back',
                        'callback_data': str(BotConfig.END)
                    }
                ]
            ]
    }