Extract config flow to own module (#13840)

* Extract config flow to own module

* Lint

* fix lint

* fix typo

* ConfigFlowHandler -> FlowHandler

* Rename to data_entry_flow
This commit is contained in:
Paulus Schoutsen 2018-04-13 10:14:53 -04:00 committed by GitHub
parent ddd2003629
commit 60508f7215
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 428 additions and 388 deletions

View file

@ -3,9 +3,8 @@ import asyncio
from unittest.mock import MagicMock, patch, mock_open
import pytest
import voluptuous as vol
from homeassistant import config_entries, loader
from homeassistant import config_entries, loader, data_entry_flow
from homeassistant.setup import async_setup_component
from tests.common import MockModule, mock_coro, MockConfigEntry
@ -100,7 +99,7 @@ def test_add_entry_calls_setup_entry(hass, manager):
'comp',
MockModule('comp', async_setup_entry=mock_setup_entry))
class TestFlow(config_entries.ConfigFlowHandler):
class TestFlow(data_entry_flow.FlowHandler):
VERSION = 1
@ -112,7 +111,7 @@ def test_add_entry_calls_setup_entry(hass, manager):
'token': 'supersecret'
})
with patch.dict(config_entries.HANDLERS, {'comp': TestFlow}):
with patch.dict(config_entries.HANDLERS, {'comp': TestFlow, 'beer': 5}):
yield from manager.flow.async_init('comp')
yield from hass.async_block_till_done()
@ -152,7 +151,7 @@ def test_domains_gets_uniques(manager):
@asyncio.coroutine
def test_saving_and_loading(hass):
"""Test that we're saving and loading correctly."""
class TestFlow(config_entries.ConfigFlowHandler):
class TestFlow(data_entry_flow.FlowHandler):
VERSION = 5
@asyncio.coroutine
@ -167,7 +166,7 @@ def test_saving_and_loading(hass):
with patch.dict(config_entries.HANDLERS, {'test': TestFlow}):
yield from hass.config_entries.flow.async_init('test')
class Test2Flow(config_entries.ConfigFlowHandler):
class Test2Flow(data_entry_flow.FlowHandler):
VERSION = 3
@asyncio.coroutine
@ -212,185 +211,6 @@ def test_saving_and_loading(hass):
assert orig.source == loaded.source
#######################
# FLOW MANAGER TESTS #
#######################
@asyncio.coroutine
def test_configure_reuses_handler_instance(manager):
"""Test that we reuse instances."""
class TestFlow(config_entries.ConfigFlowHandler):
handle_count = 0
@asyncio.coroutine
def async_step_init(self, user_input=None):
self.handle_count += 1
return self.async_show_form(
errors={'base': str(self.handle_count)},
step_id='init')
with patch.dict(config_entries.HANDLERS, {'test': TestFlow}):
form = yield from manager.flow.async_init('test')
assert form['errors']['base'] == '1'
form = yield from manager.flow.async_configure(form['flow_id'])
assert form['errors']['base'] == '2'
assert len(manager.flow.async_progress()) == 1
assert len(manager.async_entries()) == 0
@asyncio.coroutine
def test_configure_two_steps(manager):
"""Test that we reuse instances."""
class TestFlow(config_entries.ConfigFlowHandler):
VERSION = 1
@asyncio.coroutine
def async_step_init(self, user_input=None):
if user_input is not None:
self.init_data = user_input
return self.async_step_second()
return self.async_show_form(
step_id='init',
data_schema=vol.Schema([str])
)
@asyncio.coroutine
def async_step_second(self, user_input=None):
if user_input is not None:
return self.async_create_entry(
title='Test Entry',
data=self.init_data + user_input
)
return self.async_show_form(
step_id='second',
data_schema=vol.Schema([str])
)
with patch.dict(config_entries.HANDLERS, {'test': TestFlow}):
form = yield from manager.flow.async_init('test')
with pytest.raises(vol.Invalid):
form = yield from manager.flow.async_configure(
form['flow_id'], 'INCORRECT-DATA')
form = yield from manager.flow.async_configure(
form['flow_id'], ['INIT-DATA'])
form = yield from manager.flow.async_configure(
form['flow_id'], ['SECOND-DATA'])
assert form['type'] == config_entries.RESULT_TYPE_CREATE_ENTRY
assert len(manager.flow.async_progress()) == 0
assert len(manager.async_entries()) == 1
entry = manager.async_entries()[0]
assert entry.domain == 'test'
assert entry.data == ['INIT-DATA', 'SECOND-DATA']
@asyncio.coroutine
def test_show_form(manager):
"""Test that abort removes the flow from progress."""
schema = vol.Schema({
vol.Required('username'): str,
vol.Required('password'): str
})
class TestFlow(config_entries.ConfigFlowHandler):
@asyncio.coroutine
def async_step_init(self, user_input=None):
return self.async_show_form(
step_id='init',
data_schema=schema,
errors={
'username': 'Should be unique.'
}
)
with patch.dict(config_entries.HANDLERS, {'test': TestFlow}):
form = yield from manager.flow.async_init('test')
assert form['type'] == 'form'
assert form['data_schema'] is schema
assert form['errors'] == {
'username': 'Should be unique.'
}
@asyncio.coroutine
def test_abort_removes_instance(manager):
"""Test that abort removes the flow from progress."""
class TestFlow(config_entries.ConfigFlowHandler):
is_new = True
@asyncio.coroutine
def async_step_init(self, user_input=None):
old = self.is_new
self.is_new = False
return self.async_abort(reason=str(old))
with patch.dict(config_entries.HANDLERS, {'test': TestFlow}):
form = yield from manager.flow.async_init('test')
assert form['reason'] == 'True'
assert len(manager.flow.async_progress()) == 0
assert len(manager.async_entries()) == 0
form = yield from manager.flow.async_init('test')
assert form['reason'] == 'True'
assert len(manager.flow.async_progress()) == 0
assert len(manager.async_entries()) == 0
@asyncio.coroutine
def test_create_saves_data(manager):
"""Test creating a config entry."""
class TestFlow(config_entries.ConfigFlowHandler):
VERSION = 5
@asyncio.coroutine
def async_step_init(self, user_input=None):
return self.async_create_entry(
title='Test Title',
data='Test Data'
)
with patch.dict(config_entries.HANDLERS, {'test': TestFlow}):
yield from manager.flow.async_init('test')
assert len(manager.flow.async_progress()) == 0
assert len(manager.async_entries()) == 1
entry = manager.async_entries()[0]
assert entry.version == 5
assert entry.domain == 'test'
assert entry.title == 'Test Title'
assert entry.data == 'Test Data'
assert entry.source == config_entries.SOURCE_USER
@asyncio.coroutine
def test_discovery_init_flow(manager):
"""Test a flow initialized by discovery."""
class TestFlow(config_entries.ConfigFlowHandler):
VERSION = 5
@asyncio.coroutine
def async_step_discovery(self, info):
return self.async_create_entry(title=info['id'], data=info)
data = {
'id': 'hello',
'token': 'secret'
}
with patch.dict(config_entries.HANDLERS, {'test': TestFlow}):
yield from manager.flow.async_init(
'test', source=config_entries.SOURCE_DISCOVERY, data=data)
assert len(manager.flow.async_progress()) == 0
assert len(manager.async_entries()) == 1
entry = manager.async_entries()[0]
assert entry.version == 5
assert entry.domain == 'test'
assert entry.title == 'hello'
assert entry.data == data
assert entry.source == config_entries.SOURCE_DISCOVERY
async def test_forward_entry_sets_up_component(hass):
"""Test we setup the component entry is forwarded to."""
entry = MockConfigEntry(domain='original')