Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 13 additions & 10 deletions homeassistant/components/mobile_app/webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,19 @@ async def webhook_render_template(hass, config_entry, data):

@WEBHOOK_COMMANDS.register("update_location")
@validate_schema(
{
vol.Optional(ATTR_LOCATION_NAME): cv.string,
vol.Required(ATTR_GPS): cv.gps,
vol.Required(ATTR_GPS_ACCURACY): cv.positive_int,
vol.Optional(ATTR_BATTERY): cv.positive_int,
vol.Optional(ATTR_SPEED): cv.positive_int,
vol.Optional(ATTR_ALTITUDE): vol.Coerce(float),
vol.Optional(ATTR_COURSE): cv.positive_int,
vol.Optional(ATTR_VERTICAL_ACCURACY): cv.positive_int,
}
vol.Schema(
cv.key_dependency(ATTR_GPS, ATTR_GPS_ACCURACY),
{
vol.Optional(ATTR_LOCATION_NAME): cv.string,
vol.Optional(ATTR_GPS): cv.gps,
vol.Optional(ATTR_GPS_ACCURACY): cv.positive_int,
vol.Optional(ATTR_BATTERY): cv.positive_int,
vol.Optional(ATTR_SPEED): cv.positive_int,
vol.Optional(ATTR_ALTITUDE): vol.Coerce(float),
vol.Optional(ATTR_COURSE): cv.positive_int,
vol.Optional(ATTR_VERTICAL_ACCURACY): cv.positive_int,
},
)
)
async def webhook_update_location(hass, config_entry, data):
"""Handle an update location webhook."""
Expand Down
128 changes: 126 additions & 2 deletions tests/components/mobile_app/test_webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
from homeassistant.components.camera import SUPPORT_STREAM as CAMERA_SUPPORT_STREAM
from homeassistant.components.mobile_app.const import CONF_SECRET
from homeassistant.components.zone import DOMAIN as ZONE_DOMAIN
from homeassistant.const import CONF_WEBHOOK_ID
from homeassistant.const import (
CONF_WEBHOOK_ID,
STATE_HOME,
STATE_NOT_HOME,
STATE_UNKNOWN,
)
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
Expand Down Expand Up @@ -283,7 +288,46 @@ async def test_webhook_requires_encryption(webhook_client, create_registrations)
assert webhook_json["error"]["code"] == "encryption_required"


async def test_webhook_update_location(hass, webhook_client, create_registrations):
async def test_webhook_update_location_without_locations(
hass, webhook_client, create_registrations
):
"""Test that location can be updated."""

# start off with a location set by name
resp = await webhook_client.post(
"/api/webhook/{}".format(create_registrations[1]["webhook_id"]),
json={
"type": "update_location",
"data": {"location_name": STATE_HOME},
},
)

assert resp.status == HTTPStatus.OK

state = hass.states.get("device_tracker.test_1_2")
assert state is not None
assert state.state == STATE_HOME

# set location to an 'unknown' state
resp = await webhook_client.post(
"/api/webhook/{}".format(create_registrations[1]["webhook_id"]),
json={
"type": "update_location",
"data": {"altitude": 123},
},
)

assert resp.status == HTTPStatus.OK

state = hass.states.get("device_tracker.test_1_2")
assert state is not None
assert state.state == STATE_UNKNOWN
assert state.attributes["altitude"] == 123


async def test_webhook_update_location_with_gps(
hass, webhook_client, create_registrations
):
"""Test that location can be updated."""
resp = await webhook_client.post(
"/api/webhook/{}".format(create_registrations[1]["webhook_id"]),
Expand All @@ -303,6 +347,86 @@ async def test_webhook_update_location(hass, webhook_client, create_registration
assert state.attributes["altitude"] == -10


async def test_webhook_update_location_with_gps_without_accuracy(
hass, webhook_client, create_registrations
):
"""Test that location can be updated."""
resp = await webhook_client.post(
"/api/webhook/{}".format(create_registrations[1]["webhook_id"]),
json={
"type": "update_location",
"data": {"gps": [1, 2]},
},
)

assert resp.status == HTTPStatus.OK

state = hass.states.get("device_tracker.test_1_2")
assert state.state == STATE_UNKNOWN


async def test_webhook_update_location_with_location_name(
hass, webhook_client, create_registrations
):
"""Test that location can be updated."""

with patch(
"homeassistant.config.load_yaml_config_file",
autospec=True,
return_value={
ZONE_DOMAIN: [
{
"name": "zone_name",
"latitude": 1.23,
"longitude": -4.56,
"radius": 200,
"icon": "mdi:test-tube",
},
]
},
):
await hass.services.async_call(ZONE_DOMAIN, "reload", blocking=True)

resp = await webhook_client.post(
"/api/webhook/{}".format(create_registrations[1]["webhook_id"]),
json={
"type": "update_location",
"data": {"location_name": "zone_name"},
},
)

assert resp.status == HTTPStatus.OK

state = hass.states.get("device_tracker.test_1_2")
assert state.state == "zone_name"

resp = await webhook_client.post(
"/api/webhook/{}".format(create_registrations[1]["webhook_id"]),
json={
"type": "update_location",
"data": {"location_name": STATE_HOME},
},
)

assert resp.status == HTTPStatus.OK

state = hass.states.get("device_tracker.test_1_2")
assert state.state == STATE_HOME

resp = await webhook_client.post(
"/api/webhook/{}".format(create_registrations[1]["webhook_id"]),
json={
"type": "update_location",
"data": {"location_name": STATE_NOT_HOME},
},
)

assert resp.status == HTTPStatus.OK

state = hass.states.get("device_tracker.test_1_2")
assert state.state == STATE_NOT_HOME


async def test_webhook_enable_encryption(hass, webhook_client, create_registrations):
"""Test that encryption can be added to a reg initially created without."""
webhook_id = create_registrations[1]["webhook_id"]
Expand Down