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']
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
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()
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()
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']
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']]
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
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']
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']
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']
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
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
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.'
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
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()
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) } ] ] }
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()
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) } ] ] }