mirror of
https://github.com/tomaae/homeassistant-mikrotik_router.git
synced 2025-07-24 04:24:29 +02:00
added config flow test and workflow for tests
This commit is contained in:
parent
f17fefb5d8
commit
1dd4f52524
10 changed files with 1706 additions and 5 deletions
2
.github/generate_releasenotes.py
vendored
2
.github/generate_releasenotes.py
vendored
|
@ -70,6 +70,8 @@ def get_integration_commits(github, skip=True):
|
|||
continue
|
||||
if " workflow" in msg:
|
||||
continue
|
||||
if " test" in msg:
|
||||
continue
|
||||
if "docs" in msg:
|
||||
continue
|
||||
if "dev debug" in msg:
|
||||
|
|
22
.github/generate_requirements.py
vendored
Normal file
22
.github/generate_requirements.py
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
import configparser
|
||||
|
||||
|
||||
def main():
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read("Pipfile")
|
||||
|
||||
packages = "packages"
|
||||
with open("requirements.txt", "w") as f:
|
||||
for key in parser[packages]:
|
||||
value = parser[packages][key]
|
||||
f.write(key + value.replace('"', "") + "\n")
|
||||
|
||||
devpackages = "dev-packages"
|
||||
with open("requirements_tests.txt", "w") as f:
|
||||
for key in parser[devpackages]:
|
||||
value = parser[devpackages][key]
|
||||
f.write(key + value.replace('"', "") + "\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
|
@ -12,7 +12,7 @@ on:
|
|||
|
||||
jobs:
|
||||
black:
|
||||
name: Black
|
||||
name: Python Code Format Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -29,10 +29,14 @@ jobs:
|
|||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Generate Requirements lists
|
||||
run: |
|
||||
python3 .github/generate_requirements.py
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements_tests.txt
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
pip install flake8
|
||||
|
@ -40,10 +44,10 @@ jobs:
|
|||
flake8 . --count --select=E9,F63,F7,F82 --ignore W503,E722 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --exit-zero --max-complexity=15 --max-line-length=127 --statistics
|
||||
#- name: Test with pytest
|
||||
# run: |
|
||||
# pip install pytest
|
||||
# pytest
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pip install pytest
|
||||
pytest
|
||||
sonarcloud:
|
||||
name: SonarCloud
|
||||
runs-on: ubuntu-latest
|
||||
|
|
27
Pipfile
Normal file
27
Pipfile
Normal file
|
@ -0,0 +1,27 @@
|
|||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
wheel = ">=0.34"
|
||||
pygithub = ">=1.47"
|
||||
homeassistant = ">=0.108.4"
|
||||
sqlalchemy = "==1.3.16"
|
||||
codecov = "==2.0.15"
|
||||
mock-open = "==1.3.1"
|
||||
mypy = "==0.770"
|
||||
pre-commit = "==2.2.0"
|
||||
pylint = "==2.4.4"
|
||||
astroid = "==2.3.3"
|
||||
pylint-strict-informational = "==0.1"
|
||||
pytest-aiohttp = "==0.3.0"
|
||||
pytest-cov = "==2.8.1"
|
||||
pytest-sugar = "==0.9.2"
|
||||
pytest-timeout = "==1.3.3"
|
||||
pytest = "==5.3.5"
|
||||
requests_mock = "==1.7.0"
|
||||
responses = "==0.10.6"
|
||||
|
||||
[packages]
|
||||
librouteros = "==3.0.0"
|
|
@ -30,6 +30,7 @@ from .const import (
|
|||
CONF_SCAN_INTERVAL,
|
||||
DEFAULT_SCAN_INTERVAL,
|
||||
DEFAULT_UNIT_OF_MEASUREMENT,
|
||||
CONF_TRACK_HOSTS_TIMEOUT,
|
||||
)
|
||||
from .exceptions import ApiEntryNotFound
|
||||
from .helper import parse_api
|
||||
|
|
20
tests/__init__.py
Normal file
20
tests/__init__.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
"""Tests for the Mikrotik Router component."""
|
||||
|
||||
from custom_components.mikrotik_router import config_flow
|
||||
|
||||
MOCK_DATA = {
|
||||
config_flow.CONF_NAME: config_flow.DEFAULT_DEVICE_NAME,
|
||||
config_flow.CONF_HOST: config_flow.DEFAULT_HOST,
|
||||
config_flow.CONF_USERNAME: config_flow.DEFAULT_USERNAME,
|
||||
config_flow.CONF_PASSWORD: config_flow.DEFAULT_PASSWORD,
|
||||
config_flow.CONF_PORT: config_flow.DEFAULT_PORT,
|
||||
config_flow.CONF_SSL: config_flow.DEFAULT_SSL,
|
||||
}
|
||||
|
||||
MOCK_OPTIONS = {
|
||||
config_flow.CONF_SCAN_INTERVAL: config_flow.DEFAULT_SCAN_INTERVAL,
|
||||
config_flow.CONF_UNIT_OF_MEASUREMENT: config_flow.DEFAULT_UNIT_OF_MEASUREMENT,
|
||||
config_flow.CONF_TRACK_IFACE_CLIENTS: config_flow.DEFAULT_TRACK_IFACE_CLIENTS,
|
||||
config_flow.CONF_TRACK_HOSTS: config_flow.DEFAULT_TRACK_HOSTS,
|
||||
config_flow.CONF_TRACK_HOSTS_TIMEOUT: config_flow.DEFAULT_TRACK_HOST_TIMEOUT,
|
||||
}
|
1148
tests/common.py
Normal file
1148
tests/common.py
Normal file
File diff suppressed because it is too large
Load diff
253
tests/conftest.py
Normal file
253
tests/conftest.py
Normal file
|
@ -0,0 +1,253 @@
|
|||
"""Set up some common test helper things."""
|
||||
import functools
|
||||
import logging
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import requests_mock as _requests_mock
|
||||
|
||||
from homeassistant import util
|
||||
from homeassistant.auth.const import GROUP_ID_ADMIN, GROUP_ID_READ_ONLY
|
||||
from homeassistant.auth.providers import homeassistant, legacy_api_password
|
||||
from homeassistant.components.websocket_api.auth import (
|
||||
TYPE_AUTH,
|
||||
TYPE_AUTH_OK,
|
||||
TYPE_AUTH_REQUIRED,
|
||||
)
|
||||
from homeassistant.components.websocket_api.http import URL
|
||||
from homeassistant.exceptions import ServiceNotFound
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import location
|
||||
|
||||
from tests.ignore_uncaught_exceptions import (
|
||||
IGNORE_UNCAUGHT_EXCEPTIONS,
|
||||
IGNORE_UNCAUGHT_JSON_EXCEPTIONS,
|
||||
)
|
||||
|
||||
pytest.register_assert_rewrite("tests.common")
|
||||
|
||||
from tests.common import ( # noqa: E402, isort:skip
|
||||
CLIENT_ID,
|
||||
INSTANCES,
|
||||
MockUser,
|
||||
async_test_home_assistant,
|
||||
mock_coro,
|
||||
mock_storage as mock_storage,
|
||||
)
|
||||
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
|
||||
|
||||
|
||||
def check_real(func):
|
||||
"""Force a function to require a keyword _test_real to be passed in."""
|
||||
|
||||
@functools.wraps(func)
|
||||
async def guard_func(*args, **kwargs):
|
||||
real = kwargs.pop("_test_real", None)
|
||||
|
||||
if not real:
|
||||
raise Exception(
|
||||
'Forgot to mock or pass "_test_real=True" to %s', func.__name__
|
||||
)
|
||||
|
||||
return await func(*args, **kwargs)
|
||||
|
||||
return guard_func
|
||||
|
||||
|
||||
# Guard a few functions that would make network connections
|
||||
location.async_detect_location_info = check_real(location.async_detect_location_info)
|
||||
util.get_local_ip = lambda: "127.0.0.1"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def verify_cleanup():
|
||||
"""Verify that the test has cleaned up resources correctly."""
|
||||
yield
|
||||
|
||||
if len(INSTANCES) >= 2:
|
||||
count = len(INSTANCES)
|
||||
for inst in INSTANCES:
|
||||
inst.stop()
|
||||
pytest.exit(f"Detected non stopped instances ({count}), aborting test run")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_storage():
|
||||
"""Fixture to mock storage."""
|
||||
with mock_storage() as stored_data:
|
||||
yield stored_data
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass(loop, hass_storage, request):
|
||||
"""Fixture to provide a test instance of Home Assistant."""
|
||||
|
||||
def exc_handle(loop, context):
|
||||
"""Handle exceptions by rethrowing them, which will fail the test."""
|
||||
exceptions.append(context["exception"])
|
||||
orig_exception_handler(loop, context)
|
||||
|
||||
exceptions = []
|
||||
hass = loop.run_until_complete(async_test_home_assistant(loop))
|
||||
orig_exception_handler = loop.get_exception_handler()
|
||||
loop.set_exception_handler(exc_handle)
|
||||
|
||||
yield hass
|
||||
|
||||
loop.run_until_complete(hass.async_stop(force=True))
|
||||
for ex in exceptions:
|
||||
if (
|
||||
request.module.__name__,
|
||||
request.function.__name__,
|
||||
) in IGNORE_UNCAUGHT_EXCEPTIONS:
|
||||
continue
|
||||
if isinstance(ex, ServiceNotFound):
|
||||
continue
|
||||
if (
|
||||
isinstance(ex, TypeError)
|
||||
and "is not JSON serializable" in str(ex)
|
||||
and (request.module.__name__, request.function.__name__)
|
||||
in IGNORE_UNCAUGHT_JSON_EXCEPTIONS
|
||||
):
|
||||
continue
|
||||
raise ex
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def requests_mock():
|
||||
"""Fixture to provide a requests mocker."""
|
||||
with _requests_mock.mock() as m:
|
||||
yield m
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_device_tracker_conf():
|
||||
"""Prevent device tracker from reading/writing data."""
|
||||
devices = []
|
||||
|
||||
async def mock_update_config(path, id, entity):
|
||||
devices.append(entity)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.device_tracker.legacy"
|
||||
".DeviceTracker.async_update_config",
|
||||
side_effect=mock_update_config,
|
||||
), patch(
|
||||
"homeassistant.components.device_tracker.legacy.async_load_config",
|
||||
side_effect=lambda *args: mock_coro(devices),
|
||||
):
|
||||
yield devices
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_access_token(hass, hass_admin_user):
|
||||
"""Return an access token to access Home Assistant."""
|
||||
refresh_token = hass.loop.run_until_complete(
|
||||
hass.auth.async_create_refresh_token(hass_admin_user, CLIENT_ID)
|
||||
)
|
||||
return hass.auth.async_create_access_token(refresh_token)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_owner_user(hass, local_auth):
|
||||
"""Return a Home Assistant admin user."""
|
||||
return MockUser(is_owner=True).add_to_hass(hass)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_admin_user(hass, local_auth):
|
||||
"""Return a Home Assistant admin user."""
|
||||
admin_group = hass.loop.run_until_complete(
|
||||
hass.auth.async_get_group(GROUP_ID_ADMIN)
|
||||
)
|
||||
return MockUser(groups=[admin_group]).add_to_hass(hass)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_read_only_user(hass, local_auth):
|
||||
"""Return a Home Assistant read only user."""
|
||||
read_only_group = hass.loop.run_until_complete(
|
||||
hass.auth.async_get_group(GROUP_ID_READ_ONLY)
|
||||
)
|
||||
return MockUser(groups=[read_only_group]).add_to_hass(hass)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_read_only_access_token(hass, hass_read_only_user):
|
||||
"""Return a Home Assistant read only user."""
|
||||
refresh_token = hass.loop.run_until_complete(
|
||||
hass.auth.async_create_refresh_token(hass_read_only_user, CLIENT_ID)
|
||||
)
|
||||
return hass.auth.async_create_access_token(refresh_token)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def legacy_auth(hass):
|
||||
"""Load legacy API password provider."""
|
||||
prv = legacy_api_password.LegacyApiPasswordAuthProvider(
|
||||
hass,
|
||||
hass.auth._store,
|
||||
{"type": "legacy_api_password", "api_password": "test-password"},
|
||||
)
|
||||
hass.auth._providers[(prv.type, prv.id)] = prv
|
||||
return prv
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def local_auth(hass):
|
||||
"""Load local auth provider."""
|
||||
prv = homeassistant.HassAuthProvider(
|
||||
hass, hass.auth._store, {"type": "homeassistant"}
|
||||
)
|
||||
hass.auth._providers[(prv.type, prv.id)] = prv
|
||||
return prv
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_client(hass, aiohttp_client, hass_access_token):
|
||||
"""Return an authenticated HTTP client."""
|
||||
|
||||
async def auth_client():
|
||||
"""Return an authenticated client."""
|
||||
return await aiohttp_client(
|
||||
hass.http.app, headers={"Authorization": f"Bearer {hass_access_token}"}
|
||||
)
|
||||
|
||||
return auth_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def hass_ws_client(aiohttp_client, hass_access_token, hass):
|
||||
"""Websocket client fixture connected to websocket server."""
|
||||
|
||||
async def create_client(hass=hass, access_token=hass_access_token):
|
||||
"""Create a websocket client."""
|
||||
assert await async_setup_component(hass, "websocket_api", {})
|
||||
|
||||
client = await aiohttp_client(hass.http.app)
|
||||
|
||||
with patch("homeassistant.components.http.auth.setup_auth"):
|
||||
websocket = await client.ws_connect(URL)
|
||||
auth_resp = await websocket.receive_json()
|
||||
assert auth_resp["type"] == TYPE_AUTH_REQUIRED
|
||||
|
||||
if access_token is None:
|
||||
await websocket.send_json(
|
||||
{"type": TYPE_AUTH, "access_token": "incorrect"}
|
||||
)
|
||||
else:
|
||||
await websocket.send_json(
|
||||
{"type": TYPE_AUTH, "access_token": access_token}
|
||||
)
|
||||
|
||||
auth_ok = await websocket.receive_json()
|
||||
assert auth_ok["type"] == TYPE_AUTH_OK
|
||||
|
||||
# wrap in client
|
||||
websocket.client = client
|
||||
return websocket
|
||||
|
||||
return create_client
|
38
tests/ignore_uncaught_exceptions.py
Normal file
38
tests/ignore_uncaught_exceptions.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
"""List of modules that have uncaught exceptions today. Will be shrunk over time."""
|
||||
IGNORE_UNCAUGHT_EXCEPTIONS = [
|
||||
("tests.components.dyson.test_air_quality", "test_purecool_aiq_attributes"),
|
||||
("tests.components.dyson.test_air_quality", "test_purecool_aiq_update_state"),
|
||||
(
|
||||
"tests.components.dyson.test_air_quality",
|
||||
"test_purecool_component_setup_only_once",
|
||||
),
|
||||
("tests.components.dyson.test_air_quality", "test_purecool_aiq_without_discovery"),
|
||||
(
|
||||
"tests.components.dyson.test_air_quality",
|
||||
"test_purecool_aiq_empty_environment_state",
|
||||
),
|
||||
(
|
||||
"tests.components.dyson.test_climate",
|
||||
"test_setup_component_with_parent_discovery",
|
||||
),
|
||||
("tests.components.dyson.test_fan", "test_purecoollink_attributes"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_turn_on"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_set_speed"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_turn_off"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_set_dyson_speed"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_oscillate"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_set_night_mode"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_set_auto_mode"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_set_angle"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_set_flow_direction_front"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_set_timer"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_update_state"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_update_state_filter_inv"),
|
||||
("tests.components.dyson.test_fan", "test_purecool_component_setup_only_once"),
|
||||
("tests.components.dyson.test_sensor", "test_purecool_component_setup_only_once"),
|
||||
("tests.components.ios.test_init", "test_creating_entry_sets_up_sensor"),
|
||||
("tests.components.ios.test_init", "test_not_configuring_ios_not_creates_entry"),
|
||||
("tests.components.local_file.test_camera", "test_file_not_readable"),
|
||||
]
|
||||
|
||||
IGNORE_UNCAUGHT_JSON_EXCEPTIONS = []
|
186
tests/test_config_flow.py
Normal file
186
tests/test_config_flow.py
Normal file
|
@ -0,0 +1,186 @@
|
|||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
import librouteros
|
||||
import pytest
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from custom_components import mikrotik_router
|
||||
|
||||
from homeassistant.const import (
|
||||
CONF_NAME,
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
CONF_USERNAME,
|
||||
CONF_PASSWORD,
|
||||
CONF_SSL,
|
||||
)
|
||||
|
||||
from . import MOCK_DATA
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
DEMO_USER_INPUT = {
|
||||
CONF_NAME: "Home router",
|
||||
CONF_HOST: "0.0.0.0",
|
||||
CONF_USERNAME: "username",
|
||||
CONF_PASSWORD: "password",
|
||||
CONF_PORT: 8278,
|
||||
CONF_SSL: True,
|
||||
}
|
||||
|
||||
DEMO_CONFIG_ENTRY = {
|
||||
CONF_NAME: "Home router",
|
||||
CONF_HOST: "0.0.0.0",
|
||||
CONF_USERNAME: "username",
|
||||
CONF_PASSWORD: "password",
|
||||
CONF_PORT: 8278,
|
||||
CONF_SSL: True,
|
||||
mikrotik_router.mikrotik_controller.CONF_SCAN_INTERVAL: 60,
|
||||
mikrotik_router.mikrotik_controller.CONF_UNIT_OF_MEASUREMENT: "Mbps",
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_IFACE_CLIENTS: True,
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_HOSTS: True,
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_HOSTS_TIMEOUT: 180,
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(name="api")
|
||||
def mock_mikrotik_api():
|
||||
"""Mock an api."""
|
||||
with patch("librouteros.connect"):
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(name="auth_error")
|
||||
def mock_api_authentication_error():
|
||||
"""Mock an api."""
|
||||
with patch(
|
||||
"librouteros.connect",
|
||||
side_effect=librouteros.exceptions.TrapError("invalid user name or password"),
|
||||
):
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture(name="conn_error")
|
||||
def mock_api_connection_error():
|
||||
"""Mock an api."""
|
||||
with patch(
|
||||
"librouteros.connect", side_effect=librouteros.exceptions.ConnectionClosed
|
||||
):
|
||||
yield
|
||||
|
||||
|
||||
async def test_import(hass, api):
|
||||
"""Test import step."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
mikrotik_router.DOMAIN, context={"source": "import"}, data=MOCK_DATA
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["title"] == "Mikrotik"
|
||||
assert result["data"][CONF_NAME] == "Mikrotik"
|
||||
assert result["data"][CONF_HOST] == "10.0.0.1"
|
||||
assert result["data"][CONF_USERNAME] == "admin"
|
||||
assert result["data"][CONF_PASSWORD] == "admin"
|
||||
assert result["data"][CONF_PORT] == 0
|
||||
assert result["data"][CONF_SSL] is False
|
||||
|
||||
|
||||
async def test_flow_works(hass, api):
|
||||
"""Test config flow."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
mikrotik_router.DOMAIN, context={"source": "user"}
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=DEMO_USER_INPUT
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["title"] == "Home router"
|
||||
assert result["data"][CONF_NAME] == "Home router"
|
||||
assert result["data"][CONF_HOST] == "0.0.0.0"
|
||||
assert result["data"][CONF_USERNAME] == "username"
|
||||
assert result["data"][CONF_PASSWORD] == "password"
|
||||
assert result["data"][CONF_PORT] == 8278
|
||||
assert result["data"][CONF_SSL] is True
|
||||
|
||||
|
||||
async def test_options(hass):
|
||||
"""Test updating options."""
|
||||
entry = MockConfigEntry(domain=mikrotik_router.DOMAIN, data=DEMO_CONFIG_ENTRY)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.options.async_init(entry.entry_id)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "device_tracker"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
mikrotik_router.mikrotik_controller.CONF_SCAN_INTERVAL: 30,
|
||||
mikrotik_router.mikrotik_controller.CONF_UNIT_OF_MEASUREMENT: "Kbps",
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_IFACE_CLIENTS: True,
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_HOSTS: False,
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_HOSTS_TIMEOUT: 180,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
mikrotik_router.mikrotik_controller.CONF_SCAN_INTERVAL: 30,
|
||||
mikrotik_router.mikrotik_controller.CONF_UNIT_OF_MEASUREMENT: "Kbps",
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_IFACE_CLIENTS: True,
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_HOSTS: False,
|
||||
mikrotik_router.mikrotik_controller.CONF_TRACK_HOSTS_TIMEOUT: 180,
|
||||
}
|
||||
|
||||
|
||||
async def test_name_exists(hass, api):
|
||||
"""Test name already configured."""
|
||||
|
||||
entry = MockConfigEntry(domain=mikrotik_router.DOMAIN, data=DEMO_CONFIG_ENTRY)
|
||||
entry.add_to_hass(hass)
|
||||
user_input = DEMO_USER_INPUT.copy()
|
||||
user_input[CONF_HOST] = "0.0.0.1"
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
mikrotik_router.DOMAIN, context={"source": "user"}
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=user_input
|
||||
)
|
||||
|
||||
assert result["type"] == "form"
|
||||
assert result["errors"] == {"base": "name_exists"}
|
||||
|
||||
|
||||
async def test_connection_error(hass, conn_error):
|
||||
"""Test error when connection is unsuccessful."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
mikrotik_router.DOMAIN, context={"source": "user"}
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=DEMO_USER_INPUT
|
||||
)
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["errors"] == {"host": "cannot_connect"}
|
||||
|
||||
|
||||
async def test_wrong_credentials(hass, auth_error):
|
||||
"""Test error when credentials are wrong."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
mikrotik_router.DOMAIN, context={"source": "user"}
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input=DEMO_USER_INPUT
|
||||
)
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["errors"] == {"host": "cannot_connect"}
|
Loading…
Add table
Add a link
Reference in a new issue