Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Samsung TV config flow #28306

Merged
merged 79 commits into from
Jan 10, 2020
Merged
Changes from 1 commit
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
7dfe213
add config flow
escoand Oct 28, 2019
7e20322
add tests
escoand Oct 28, 2019
9cd7e74
add user step error handling
escoand Oct 29, 2019
d9dcede
remove unload function
escoand Oct 29, 2019
6d3dc31
add missing test file
escoand Oct 29, 2019
4a4f5ff
handle authentication correctly
escoand Oct 31, 2019
354c14c
remove old discovery mode
escoand Oct 31, 2019
235dc19
better handling of remote class
escoand Oct 31, 2019
1f66234
optimized abort messages
escoand Oct 31, 2019
0aa3ba9
add already configured test for user flow
escoand Oct 31, 2019
afde939
Import order
escoand Oct 31, 2019
e407dbc
use ip property instead context
escoand Oct 31, 2019
7dfadaf
Black
escoand Nov 1, 2019
d08be7c
small syntax
escoand Nov 1, 2019
2603a0f
use snake_case
escoand Nov 1, 2019
acfe3d3
Revert "use ip property instead context"
escoand Nov 1, 2019
0a8b998
disable wrong pylint errors
escoand Nov 1, 2019
df25329
disable wrong no-member
escoand Nov 3, 2019
e31b5d5
Try to fix review comments
escoand Nov 4, 2019
ecdcd03
Try to fix review comments
escoand Nov 4, 2019
c81f2a2
Fix missing self
escoand Nov 4, 2019
0020628
Fix ip checks
escoand Nov 4, 2019
1d7bd27
methods to functions
escoand Nov 4, 2019
181f144
simplify user check
escoand Nov 4, 2019
d80505f
remove user errors
escoand Nov 4, 2019
d664008
use async_setup for config
escoand Nov 6, 2019
88783d2
fix after rebase
escoand Nov 6, 2019
520c6b8
import config to user config flow
escoand Nov 13, 2019
d05e28a
patch all samsungctl
escoand Nov 13, 2019
a642c7b
fix after rebase
escoand Nov 17, 2019
076f44f
fix notes
escoand Nov 18, 2019
7355732
remove unused variable
escoand Nov 18, 2019
5d7d37e
ignore old setup function
escoand Nov 18, 2019
d65c4db
Merge remote-tracking branch 'upstream/dev' into samsungtv_configflow
escoand Jan 2, 2020
967f376
fix after merge
escoand Jan 2, 2020
dceea6f
pass configuration to import step
escoand Jan 2, 2020
35ab5d2
isort
escoand Jan 2, 2020
86df0b3
fix recursion
escoand Jan 2, 2020
d5a7375
remove timeout config
escoand Jan 3, 2020
5a77dcd
add turn on action (dry without testing)
escoand Jan 3, 2020
d5513b5
use upstream checks
escoand Jan 3, 2020
657c830
cleanup
escoand Jan 3, 2020
af536ba
minor
escoand Jan 3, 2020
3d3f36f
correctly await async method
escoand Jan 3, 2020
4095de8
ignore unused import
escoand Jan 3, 2020
f370578
async call send_key
escoand Jan 3, 2020
a0c8bc0
Revert "async call send_key"
escoand Jan 4, 2020
9d0255a
fix comments
escoand Jan 4, 2020
ab14205
fix timeout test
escoand Jan 4, 2020
a982f79
test turn on action
escoand Jan 4, 2020
6bf90c4
Update media_player.py
escoand Jan 4, 2020
6f58951
Update test_media_player.py
escoand Jan 4, 2020
22f5a83
Merge branch 'dev' into samsungtv_configflow
escoand Jan 4, 2020
dc6fe0d
Update test_media_player.py
escoand Jan 4, 2020
6de9f5d
use async executor
escoand Jan 5, 2020
c28015a
use newer ssdp data
escoand Jan 5, 2020
4ee7c3e
update manually configured with ssdp data
escoand Jan 5, 2020
248b1c2
dont setup component directly
escoand Jan 5, 2020
d935ef1
ensure list
escoand Jan 5, 2020
dd1b445
check updated device info
escoand Jan 5, 2020
f7e1b4d
Update config_flow.py
escoand Jan 6, 2020
a6014e7
Update __init__.py
escoand Jan 6, 2020
7956d7a
fix duplicate check
escoand Jan 6, 2020
a695fd7
simplified unique check
escoand Jan 6, 2020
67c3375
move method detection to config_flow
escoand Jan 6, 2020
8c5b64b
move unique test to init
escoand Jan 6, 2020
8d2d1fa
fix after real world test
escoand Jan 6, 2020
27987d1
Merge branch 'dev' into samsungtv_configflow
escoand Jan 8, 2020
31e7e6e
optimize config_validation
escoand Jan 8, 2020
ee1d275
update device_info on ssdp discovery
escoand Jan 8, 2020
4432c2d
Merge remote-tracking branch 'upstream/dev' into samsungtv_configflow
escoand Jan 8, 2020
405b0b5
cleaner update listener
escoand Jan 9, 2020
68ed565
fix lint
escoand Jan 9, 2020
4906638
fix method signature
escoand Jan 9, 2020
955311c
add note for manual config to confirm message
escoand Jan 9, 2020
5b5092f
fix turn_on_action
escoand Jan 9, 2020
37bf6fc
pass script
escoand Jan 9, 2020
7b406a2
patch delay
escoand Jan 9, 2020
ede0fce
remove device info update
escoand Jan 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add missing test file
  • Loading branch information
escoand committed Nov 17, 2019
commit 6d3dc31738d93b2f74f20ad802e521829787abda
244 changes: 244 additions & 0 deletions tests/components/samsungtv/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
"""Tests for Samsung TV config flow."""
from asynctest import mock
import pytest
from samsungctl.exceptions import AccessDenied, UnhandledResponse
from unittest.mock import patch

from homeassistant.components.samsungtv.const import (
CONF_MANUFACTURER,
CONF_MODEL,
DOMAIN,
)
from homeassistant.components.ssdp import (
ATTR_HOST,
ATTR_NAME,
ATTR_MODEL_NAME,
ATTR_MANUFACTURER,
ATTR_UDN,
)
from homeassistant.const import CONF_HOST, CONF_ID, CONF_NAME

MOCK_USER_DATA = {CONF_HOST: "fake_host", CONF_NAME: "fake_name"}
MOCK_SSDP_DATA = {
ATTR_HOST: "fake_host",
ATTR_NAME: "[TV]fake_name",
ATTR_MANUFACTURER: "fake_manufacturer",
ATTR_MODEL_NAME: "fake_model",
ATTR_UDN: "uuid:fake_uuid",
}
MOCK_SSDP_DATA_NOPREFIX = {
ATTR_HOST: "fake2_host",
ATTR_NAME: "fake2_name",
ATTR_MANUFACTURER: "fake2_manufacturer",
ATTR_MODEL_NAME: "fake2_model",
ATTR_UDN: "fake2_uuid",
}


@pytest.fixture(name="remote")
def remote_fixture():
"""Patch the samsungctl Remote."""
with patch("samsungctl.Remote") as remote_class, patch(
"homeassistant.components.samsungtv.config_flow.socket"
) as socket_class:
remote = mock.Mock()
remote_class.return_value = remote
socket = mock.Mock()
socket_class.return_value = socket
yield remote


async def test_user(hass, remote):
"""Test starting a flow by user."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_USER_DATA
)
assert result["type"] == "create_entry"
assert result["title"] == "fake_name"
assert result["data"][CONF_HOST] == "fake_host"
assert result["data"][CONF_NAME] is None
assert result["data"][CONF_MANUFACTURER] is None
assert result["data"][CONF_MODEL] is None
assert result["data"][CONF_ID] is None


async def test_user_empty(hass, remote):
"""Test starting a flow by user."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}
)
assert result["type"] == "form"
assert result["step_id"] == "user"


async def test_user_error(hass, remote):
"""Test starting a flow by user."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data={}
)
assert result["type"] == "form"
assert len(result["errors"]) == 2
assert result["errors"][CONF_HOST] is not None
assert result["errors"][CONF_NAME] is not None

result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data={CONF_HOST: "test"}
)
assert result["type"] == "form"
assert len(result["errors"]) == 1
assert result["errors"][CONF_NAME] is not None


async def test_user_auth(hass):
"""Test starting a flow from discovery."""
with patch(
"homeassistant.components.samsungtv.config_flow.Remote",
side_effect=[AccessDenied("Boom"), mock.DEFAULT],
), patch("homeassistant.components.samsungtv.config_flow.socket"):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_USER_DATA
)
assert result["type"] == "form"
assert result["step_id"] == "user_auth"

result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input="whatever"
)
assert result["type"] == "create_entry"


async def test_user_not_supported(hass):
"""Test starting a flow from discovery."""
with patch(
"homeassistant.components.samsungtv.config_flow.Remote",
side_effect=UnhandledResponse("Boom"),
), patch("homeassistant.components.samsungtv.config_flow.socket"):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_USER_DATA
)
assert result["type"] == "abort"
assert result["reason"] == "not_supported"


async def test_user_not_found(hass):
"""Test starting a flow from discovery."""
with patch(
"homeassistant.components.samsungtv.config_flow.Remote",
side_effect=OSError("Boom"),
), patch("homeassistant.components.samsungtv.config_flow.socket"):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_USER_DATA
)
assert result["type"] == "abort"
assert result["reason"] == "not_found"


async def test_ssdp(hass, remote):
"""Test starting a flow from discovery."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)
assert result["type"] == "form"
assert result["step_id"] == "confirm"

result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input="whatever"
)
assert result["type"] == "create_entry"
assert result["title"] == "fake_name (fake_model)"
assert result["data"][CONF_HOST] == "fake_host"
assert result["data"][CONF_NAME] == "fake_name"
assert result["data"][CONF_MANUFACTURER] == "fake_manufacturer"
assert result["data"][CONF_MODEL] == "fake_model"
assert result["data"][CONF_ID] == "fake_uuid"


async def test_ssdp_noprefix(hass, remote):
"""Test starting a flow from discovery."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA_NOPREFIX
)
assert result["type"] == "form"
assert result["step_id"] == "confirm"

result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input="whatever"
)
assert result["type"] == "create_entry"
assert result["title"] == "fake2_name (fake2_model)"
assert result["data"][CONF_HOST] == "fake2_host"
assert result["data"][CONF_NAME] == "fake2_name"
assert result["data"][CONF_MANUFACTURER] == "fake2_manufacturer"
assert result["data"][CONF_MODEL] == "fake2_model"
assert result["data"][CONF_ID] == "fake2_uuid"


async def test_ssdp_auth(hass):
"""Test starting a flow from discovery."""
with patch(
"homeassistant.components.samsungtv.config_flow.Remote",
side_effect=[AccessDenied("Boom"), mock.DEFAULT],
), patch("homeassistant.components.samsungtv.config_flow.socket"):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)
assert result["type"] == "form"
assert result["step_id"] == "ssdp_auth"

result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input="whatever"
)
assert result["type"] == "form"
assert result["step_id"] == "confirm"


async def test_ssdp_not_supported(hass):
"""Test starting a flow from discovery."""
with patch(
"homeassistant.components.samsungtv.config_flow.Remote",
side_effect=UnhandledResponse("Boom"),
), patch("homeassistant.components.samsungtv.config_flow.socket"):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)
assert result["type"] == "abort"
assert result["reason"] == "not_supported"


async def test_ssdp_not_found(hass):
"""Test starting a flow from discovery."""
with patch(
"homeassistant.components.samsungtv.config_flow.Remote",
side_effect=OSError("Boom"),
), patch("homeassistant.components.samsungtv.config_flow.socket"):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)
assert result["type"] == "abort"
assert result["reason"] == "not_found"


async def test_discovery_already_in_progress(hass, remote):
"""Test starting a flow from discovery."""
await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)

result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)
assert result["type"] == "abort"
assert result["reason"] == "already_in_progress"


async def test_discovery_already_configured(hass, remote):
"""Test starting a flow from discovery."""
await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_USER_DATA
)

result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "ssdp"}, data=MOCK_SSDP_DATA
)
assert result["type"] == "abort"
assert result["reason"] == "already_configured"