Exemplo n.º 1
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']]
Exemplo n.º 2
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()
Exemplo n.º 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()
Exemplo n.º 4
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
Exemplo n.º 5
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']
Exemplo n.º 6
0
def test_init_ok(mocker: pytest_mock.mocker) -> None:
    """
    Tests CameraDevice instance construction.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker, reader=False)

    CameraDevice()
Exemplo n.º 7
0
def test_init_camera_connection_error(mocker: pytest_mock.mocker) -> None:
    """
    Tests CameraDevice instantiation when device is not reachable.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker, reader=False, opened=False)

    with pytest.raises(CameraConnectionError):
        CameraDevice()
Exemplo n.º 8
0
def test_init_codec_not_available(mocker: pytest_mock.mocker) -> None:
    """
    Tests Camera instantiation when codec is not available.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker, reader=False)
    mock_bad_video_writer(mocker)

    with pytest.raises(CodecNotAvailable):
        Camera()
Exemplo n.º 9
0
def test_start_and_stop(mocker: pytest_mock.mocker) -> None:
    """
    Tests camera device starting and stopping.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker, reader=False)

    camera_device = CameraDevice()
    camera_device.start()
    camera_device.stop()
Exemplo n.º 10
0
def test_frame_size(mocker: pytest_mock.mocker) -> None:
    """
    Tests frame size value.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker)

    camera_device = CameraDevice()
    camera_device.start()
    assert camera_device.frame_size == FRAME_SIZE
    camera_device.stop()
Exemplo n.º 11
0
def test_init_logging_level(mocker: pytest_mock.mocker) -> None:
    """
    Tests Bot instantiation with logging level modification.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker, reader=False)

    bot = Bot(token='FAKE_TOKEN', username='******', log_level='WARNING')
    assert bot.logger.getEffectiveLevel() == logging.WARNING

    bot = Bot(token='FAKE_TOKEN', username='******', log_level='INFO')
    assert bot.logger.getEffectiveLevel() == logging.INFO
Exemplo n.º 12
0
def test_fps(mocker: pytest_mock.mocker) -> None:
    """
    Tests fps value.

    The testing has +/- 5 fps of tolerance.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker)

    camera_device = CameraDevice()
    camera_device.start()
    time.sleep(0.5)
    assert abs(camera_device.fps) - FPS < 5  # FPS +/- 5
    camera_device.stop()
Exemplo n.º 13
0
def test_init_without_camera(caplog: _pytest.logging.caplog,
                             mocker: pytest_mock.mocker) -> None:
    """
    Tests Bot instantiation when device is not reachable.

    Args:
        caplog: Fixture for log messages capturing.
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker, reader=False, opened=False)
    with pytest.raises(SystemExit) as error:
        Bot(token='FAKE_TOKEN', username='******')
    assert len(caplog.records) == 1
    record: logging.LogRecord = caplog.records[0]
    assert record.levelno == logging.CRITICAL
    assert 'camera' in record.message
    assert error.type == SystemExit
    assert error.value.code == 2
Exemplo n.º 14
0
def test_get_video(mocker: pytest_mock.mocker) -> None:
    """
    Tests video taking method.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker)

    camera = Camera()
    camera.start()
    sleep(0.5)  # Wait for fps calculation

    video = camera.get_video(seconds=0.5)
    # Checks MP4 magic numbers
    assert video.read(12) == b'\x00\x00\x00\x1cftypisom'

    camera.stop()
Exemplo n.º 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()
Exemplo n.º 16
0
def test_persistence_dir(tmp_path: _pytest.tmpdir.tmp_path,
                         mocker: pytest_mock.mocker) -> None:
    """
    Tests Bot instantiation passing a directory for data persistence.

    Args:
        tmp_path: Fixture for temporary path handling.
        mocker: Fixture for object mocking.
    """
    mock_telegram_updater(mocker)
    mock_video_capture(mocker, reader=False)

    persistence_dir = tmp_path / "test"
    assert not persistence_dir.exists()

    Bot(token='FAKE_TOKEN',
        username='******',
        persistence_dir=str(persistence_dir))
    assert persistence_dir.exists()
Exemplo n.º 17
0
def test_start_and_stop(caplog: _pytest.logging.caplog,
                        mocker: pytest_mock.mocker) -> None:
    """
    Tests Bot process starting and stopping.

    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='******')
    bot.start()
    assert len(caplog.records) == 2
    record = caplog.records[0]
    assert record.levelno == logging.INFO
    assert 'started' in record.message
    record = caplog.records[1]
    assert record.levelno == logging.INFO
    assert 'stopped' in record.message
Exemplo n.º 18
0
def test_get_photo(mocker: pytest_mock.mocker) -> None:
    """
    Tests photo taking method.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker)

    camera = Camera()
    camera.start()

    # Photo without timestamp
    image = camera.get_photo(False)
    assert md5(image.read()).hexdigest() in FRAMES_MD5

    # Photo with timestamp
    image = camera.get_photo()
    assert md5(image.read()).hexdigest() not in FRAMES_MD5

    camera.stop()
Exemplo n.º 19
0
def test_detect_duplicated_frames(mocker: pytest_mock.mocker) -> None:
    """
    Tests duplicated frames detection.

    Frame requesting can be faster than device frame grabbing, so the same
    frame can be retrieved more than once. This test simulates a very low
    framerate and then tries to detect motion (two consecutive frames are
    different).

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker, fps=5)

    camera = Camera()
    camera.start()

    gen = camera.surveillance_start(video_seconds=0.1)
    assert 'detected' in next(gen)
    camera.surveillance_stop()

    camera.stop()
Exemplo n.º 20
0
def test_read(mocker: pytest_mock.mocker) -> None:
    """
    Tests frame reading method.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker)

    camera_device = CameraDevice()
    camera_device.start()
    frame_id, frame = camera_device.read()

    # Check types
    assert isinstance(frame_id, int)
    assert isinstance(frame, np.ndarray)

    # Check new frame
    frame_id = camera_device.read()[0]
    time.sleep(1 / FPS * 2)  # Wait until next frame is available
    assert frame_id < camera_device.read()[0]

    camera_device.stop()
Exemplo n.º 21
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()
Exemplo n.º 22
0
def test_surveillance_mode(mocker: pytest_mock.mocker) -> None:
    """
    Tests surveillance mode process.

    Args:
        mocker: Fixture for object mocking.
    """
    mock_video_capture(mocker)

    camera = Camera()
    camera.start()
    sleep(0.5)  # Wait for fps calculation

    gen = camera.surveillance_start(video_seconds=1, picture_seconds=0.8)

    assert 'detected' in next(gen)
    assert camera.is_surveillance_active is True
    assert 'photo' in next(gen)
    assert 'video' in next(gen)
    assert 'detected' in next(gen)
    camera.surveillance_stop()
    assert camera.is_surveillance_active is False

    camera.stop()