hass-core/tests/components/syncthing/test_config_flow.py
Gleb Sinyavskiy 97eb4c6c62
Add syncthing integration (#38331)
* Scaffold the integration

* Add config flow data schema

* Handle configuration errors

* Get folder states

* Support https

* Fix translations

* Listen to syncthing events in a separate thread

* Bump syncthing

* Automatically reconnect to the syncthing server

* Renames

* Improve loading and unloading

* Update folder states from events

* Refactoring, handle FolderPaused event

* Dynamic folder icons

* Refactoring

* Mark folders as unavailable when senrver is unavailable

* Update folder satus when server is available

* Raise PlatformNotReady

* Implement additional polling

* Stop polling when the server is not available

* Minor fixes

* Remove logging

* Check name uniqueness

* Refactoring

* Minor refactorings

* Bump python-syncthing

* Migrate to aiosyncthing

* Minor fixes

* Update .coveragerc

* Set quality scale

* Bump aiosyncthing, properly handle invalid token

* Fix logging

* Fix logging

* Use CONF_VERIFY_SSL from homeassistant.const

* Bump aiosyncthing. Add Syncthing device

* Fix device name

* Bump aiosyncthing

* Bump aiosyncthing

* Extract SyncthingClient

* Add folder to device_state_attributes

* Do not pass the loop

* Cover config_flow.py

* Move self.async_create_entry outside of the try block

* Raise ConfigEntryNotReady if syncthing server is not reachable

* Fix already configured error message

* Change default name to Syncthing

* Bump aiosyncthing

* Fix formatting

* Fix formatting

* Fix tests

* Fix typo, use lis comprehension

* Fix typo, remove unused CONFIG_SCHEMA

* Bump aiosyncthing

* Remove periods from log messages W0001

* Fix tests

* Black, isort

* Remove empty items from manifest.json

* Fix variable naming

* Remove async_setup

* Use SensorEntity

* Use asyncio.create_task instead of self._hass.loop.create_task

* Do not pass hass to FolderSensor initializer

* Rename device_state_attributes to extra_state_attributes

* Use callbacks

* Simplify tests

* Refactor _listen()

* Use url for the title

* Use the url instead of the name to identify the config entry

* Explicitly set sensor attributes, extract _filter_state

* Use server url instead of name in device_info

* Use server url instead of name in logs

* User server id as a device identifier

* Use URL instead of name to identify config entry

* Use shortened server id instead of name to build entity name and unique id

* Do not use CONF_NAME

* Cleanup unused strings

* Cleanup unused strings

* Add IOT class

* Scaffold the integration

* Add config flow data schema

* Handle configuration errors

* Get folder states

* Support https

* Fix translations

* Listen to syncthing events in a separate thread

* Bump syncthing

* Automatically reconnect to the syncthing server

* Renames

* Improve loading and unloading

* Update folder states from events

* Refactoring, handle FolderPaused event

* Dynamic folder icons

* Refactoring

* Mark folders as unavailable when senrver is unavailable

* Update folder satus when server is available

* Raise PlatformNotReady

* Implement additional polling

* Stop polling when the server is not available

* Minor fixes

* Remove logging

* Check name uniqueness

* Refactoring

* Minor refactorings

* Bump python-syncthing

* Migrate to aiosyncthing

* Minor fixes

* Update .coveragerc

* Set quality scale

* Bump aiosyncthing, properly handle invalid token

* Fix logging

* Fix logging

* Use CONF_VERIFY_SSL from homeassistant.const

* Bump aiosyncthing. Add Syncthing device

* Fix device name

* Bump aiosyncthing

* Bump aiosyncthing

* Extract SyncthingClient

* Add folder to device_state_attributes

* Do not pass the loop

* Cover config_flow.py

* Move self.async_create_entry outside of the try block

* Raise ConfigEntryNotReady if syncthing server is not reachable

* Fix already configured error message

* Change default name to Syncthing

* Bump aiosyncthing

* Fix formatting

* Fix formatting

* Fix tests

* Fix typo, use lis comprehension

* Fix typo, remove unused CONFIG_SCHEMA

* Bump aiosyncthing

* Remove periods from log messages W0001

* Fix tests

* Black, isort

* Remove empty items from manifest.json

* Fix variable naming

* Remove async_setup

* Use SensorEntity

* Use asyncio.create_task instead of self._hass.loop.create_task

* Do not pass hass to FolderSensor initializer

* Rename device_state_attributes to extra_state_attributes

* Use callbacks

* Simplify tests

* Refactor _listen()

* Use url for the title

* Use the url instead of the name to identify the config entry

* Explicitly set sensor attributes, extract _filter_state

* Use server url instead of name in device_info

* Use server url instead of name in logs

* User server id as a device identifier

* Use URL instead of name to identify config entry

* Use shortened server id instead of name to build entity name and unique id

* Do not use CONF_NAME

* Cleanup unused strings

* Cleanup unused strings

* Add IOT class

* Apply suggestions from code review

* Clean up

* Fix dict comprehension

* Clean sensor

* Use the server ID as a config entry unique ID

* Remove the AlreadyConfigured exception

* Clean up old error string

* Format json

* Convert sensor attributes to snake case

* Force CI

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
2021-05-08 19:12:14 +02:00

106 lines
3.4 KiB
Python

"""Tests for syncthing config flow."""
from unittest.mock import patch
from aiosyncthing.exceptions import UnauthorizedError
from homeassistant import config_entries, data_entry_flow, setup
from homeassistant.components.syncthing.const import DOMAIN
from homeassistant.const import CONF_NAME, CONF_TOKEN, CONF_URL, CONF_VERIFY_SSL
from tests.common import MockConfigEntry
NAME = "Syncthing"
URL = "http://127.0.0.1:8384"
TOKEN = "token"
VERIFY_SSL = True
MOCK_ENTRY = {
CONF_NAME: NAME,
CONF_URL: URL,
CONF_TOKEN: TOKEN,
CONF_VERIFY_SSL: VERIFY_SSL,
}
async def test_show_setup_form(hass):
"""Test that the setup form is served."""
await setup.async_setup_component(hass, "persistent_notification", {})
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {}
assert result["step_id"] == "user"
async def test_flow_successfull(hass):
"""Test with required fields only."""
with patch(
"aiosyncthing.system.System.status", return_value={"myID": "server-id"}
), patch(
"homeassistant.components.syncthing.async_setup_entry",
return_value=True,
) as mock_setup_entry:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": "user"},
data={
CONF_NAME: NAME,
CONF_URL: URL,
CONF_TOKEN: TOKEN,
CONF_VERIFY_SSL: VERIFY_SSL,
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["title"] == "http://127.0.0.1:8384"
assert result["data"][CONF_NAME] == NAME
assert result["data"][CONF_URL] == URL
assert result["data"][CONF_TOKEN] == TOKEN
assert result["data"][CONF_VERIFY_SSL] == VERIFY_SSL
assert len(mock_setup_entry.mock_calls) == 1
async def test_flow_already_configured(hass):
"""Test name is already configured."""
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_ENTRY, unique_id="server-id")
entry.add_to_hass(hass)
with patch("aiosyncthing.system.System.status", return_value={"myID": "server-id"}):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": "user"},
data=MOCK_ENTRY,
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
async def test_flow_invalid_auth(hass):
"""Test invalid auth."""
with patch("aiosyncthing.system.System.status", side_effect=UnauthorizedError):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": "user"},
data=MOCK_ENTRY,
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"]["token"] == "invalid_auth"
async def test_flow_cannot_connect(hass):
"""Test cannot connect."""
with patch("aiosyncthing.system.System.status", side_effect=Exception):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": "user"},
data=MOCK_ENTRY,
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"]["base"] == "cannot_connect"