Skip to content

Commit

Permalink
Add config_flow to shopping_list (home-assistant#32388)
Browse files Browse the repository at this point in the history
* Add config_flow to shopping_list

* Fix pylint unused import error

* Use _abort_if_unique_id_configured

* Remove SHOPPING_LIST const

* Use const.py for DOMAIN and CONF_TYPE

* Fix tests

* Remove unchanged variable _errors

* Revert CONF_TYPE (wrong usage)

* Use consts in test

* Remove import check

* Remove data={}

* Remove parameters and default values

* Re-add data={}, because it's needed

* Unique ID checks and reverts for default parameters

* remove pylint comment

* Remove block till done

* Address change requests

* Update homeassistant/components/shopping_list/strings.json

Co-Authored-By: Quentame <[email protected]>

* Update homeassistant/components/shopping_list/strings.json

Co-Authored-By: Quentame <[email protected]>

* Update tests/components/shopping_list/test_config_flow.py

Co-Authored-By: Quentame <[email protected]>

* Update tests/components/shopping_list/test_config_flow.py

Co-Authored-By: Quentame <[email protected]>

* Update tests/components/shopping_list/test_config_flow.py

Co-Authored-By: Quentame <[email protected]>

* Update tests/components/shopping_list/test_config_flow.py

Co-Authored-By: Quentame <[email protected]>

* Only test config_flow

* Generate translations

* Move data to end

* @asyncio.coroutine --> async def, yield from --> await

* @asyncio.coroutine --> async def, yield from --> await (tests)

* Remove init in config flow

* remove if not hass.config_entries.async_entries(DOMAIN)

* Add DOMAIN not in config

* Fix tests

* Update homeassistant/components/shopping_list/config_flow.py

Co-Authored-By: Paulus Schoutsen <[email protected]>

* Fix tests

* Update homeassistant/components/shopping_list/__init__.py

Co-Authored-By: Martin Hjelmare <[email protected]>

Co-authored-by: Quentame <[email protected]>
Co-authored-by: Paulus Schoutsen <[email protected]>
Co-authored-by: Martin Hjelmare <[email protected]>
  • Loading branch information
4 people authored Mar 6, 2020
1 parent e1cc2ac commit 8f2567f
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 65 deletions.
14 changes: 14 additions & 0 deletions homeassistant/components/shopping_list/.translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"config": {
"abort": {
"already_configured": "The shopping list is already configured."
},
"step": {
"user": {
"description": "Do you want to configure the shopping list?",
"title": "Shopping List"
}
},
"title": "Shopping List"
}
}
34 changes: 23 additions & 11 deletions homeassistant/components/shopping_list/__init__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
"""Support to manage a shopping list."""
import asyncio
import logging
import uuid

import voluptuous as vol

from homeassistant import config_entries
from homeassistant.components import http, websocket_api
from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.const import HTTP_BAD_REQUEST, HTTP_NOT_FOUND
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.util.json import load_json, save_json

from .const import DOMAIN

ATTR_NAME = "name"

DOMAIN = "shopping_list"
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema({DOMAIN: {}}, extra=vol.ALLOW_EXTRA)
EVENT = "shopping_list_updated"
Expand Down Expand Up @@ -53,20 +54,32 @@
)


@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Initialize the shopping list."""

@asyncio.coroutine
def add_item_service(call):
if DOMAIN not in config:
return True

hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}
)
)

return True


async def async_setup_entry(hass, config_entry):
"""Set up shopping list from config flow."""

async def add_item_service(call):
"""Add an item with `name`."""
data = hass.data[DOMAIN]
name = call.data.get(ATTR_NAME)
if name is not None:
data.async_add(name)

@asyncio.coroutine
def complete_item_service(call):
async def complete_item_service(call):
"""Mark the item provided via `name` as completed."""
data = hass.data[DOMAIN]
name = call.data.get(ATTR_NAME)
Expand All @@ -80,7 +93,7 @@ def complete_item_service(call):
data.async_update(item["id"], {"name": name, "complete": True})

data = hass.data[DOMAIN] = ShoppingData(hass)
yield from data.async_load()
await data.async_load()

hass.services.async_register(
DOMAIN, SERVICE_ADD_ITEM, add_item_service, schema=SERVICE_ITEM_SCHEMA
Expand Down Expand Up @@ -206,8 +219,7 @@ class CreateShoppingListItemView(http.HomeAssistantView):
name = "api:shopping_list:item"

@RequestDataValidator(vol.Schema({vol.Required("name"): str}))
@asyncio.coroutine
def post(self, request, data):
async def post(self, request, data):
"""Create a new shopping list item."""
item = request.app["hass"].data[DOMAIN].async_add(data["name"])
request.app["hass"].bus.async_fire(EVENT)
Expand Down
24 changes: 24 additions & 0 deletions homeassistant/components/shopping_list/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Config flow to configure ShoppingList component."""
from homeassistant import config_entries

from .const import DOMAIN


class ShoppingListFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Config flow for ShoppingList component."""

VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH

async def async_step_user(self, user_input=None):
"""Handle a flow initialized by the user."""
# Check if already configured
await self.async_set_unique_id(DOMAIN)
self._abort_if_unique_id_configured()

if user_input is not None:
return self.async_create_entry(title="Shopping List", data=user_input)

return self.async_show_form(step_id="user")

async_step_import = async_step_user
2 changes: 2 additions & 0 deletions homeassistant/components/shopping_list/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"""All constants related to the shopping list component."""
DOMAIN = "shopping_list"
1 change: 1 addition & 0 deletions homeassistant/components/shopping_list/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"requirements": [],
"dependencies": ["http"],
"codeowners": [],
"config_flow": true,
"quality_scale": "internal"
}
14 changes: 14 additions & 0 deletions homeassistant/components/shopping_list/strings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"config": {
"title": "Shopping List",
"step": {
"user": {
"title": "Shopping List",
"description": "Do you want to configure the shopping list?"
}
},
"abort": {
"already_configured": "The shopping list is already configured."
}
}
}
1 change: 1 addition & 0 deletions homeassistant/generated/config_flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"samsungtv",
"sense",
"sentry",
"shopping_list",
"simplisafe",
"smartthings",
"smhi",
Expand Down
13 changes: 9 additions & 4 deletions tests/components/shopping_list/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Shopping list test helpers."""
from unittest.mock import patch

from asynctest import patch
import pytest

from homeassistant.components.shopping_list import intent as sl_intent
from homeassistant.setup import async_setup_component

from tests.common import MockConfigEntry


@pytest.fixture(autouse=True)
Expand All @@ -19,5 +19,10 @@ def mock_shopping_list_io():
@pytest.fixture
async def sl_setup(hass):
"""Set up the shopping list."""
assert await async_setup_component(hass, "shopping_list", {})

entry = MockConfigEntry(domain="shopping_list")
entry.add_to_hass(hass)

assert await hass.config_entries.async_setup(entry.entry_id)

await sl_intent.async_setup_intents(hass)
36 changes: 36 additions & 0 deletions tests/components/shopping_list/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Test config flow."""

from homeassistant import data_entry_flow
from homeassistant.components.shopping_list.const import DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER


async def test_import(hass):
"""Test entry will be imported."""

result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data={}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY


async def test_user(hass):
"""Test we can start a config flow."""

result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)

assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "user"


async def test_user_confirm(hass):
"""Test we can finish a config flow."""

result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data={}
)

assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["result"].data == {}
Loading

0 comments on commit 8f2567f

Please sign in to comment.