mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Use a mocked API client in Traccar Server tests (#109358)
This commit is contained in:
parent
1f466e737e
commit
025fe51322
@ -3,12 +3,79 @@ from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
from pytraccar import ApiClient
|
||||
|
||||
from homeassistant.components.traccar_server.const import (
|
||||
CONF_CUSTOM_ATTRIBUTES,
|
||||
CONF_EVENTS,
|
||||
CONF_MAX_ACCURACY,
|
||||
CONF_SKIP_ACCURACY_FILTER_FOR,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
CONF_SSL,
|
||||
CONF_USERNAME,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
load_json_array_fixture,
|
||||
load_json_object_fixture,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
|
||||
"""Override async_setup_entry."""
|
||||
def mock_traccar_api_client() -> Generator[AsyncMock, None, None]:
|
||||
"""Mock a Traccar ApiClient client."""
|
||||
with patch(
|
||||
"homeassistant.components.traccar_server.async_setup_entry", return_value=True
|
||||
) as mock_setup_entry:
|
||||
yield mock_setup_entry
|
||||
"homeassistant.components.traccar_server.ApiClient",
|
||||
autospec=True,
|
||||
) as mock_client, patch(
|
||||
"homeassistant.components.traccar_server.config_flow.ApiClient",
|
||||
new=mock_client,
|
||||
):
|
||||
client: ApiClient = mock_client.return_value
|
||||
client.get_devices.return_value = load_json_array_fixture(
|
||||
"traccar_server/devices.json"
|
||||
)
|
||||
client.get_geofences.return_value = load_json_array_fixture(
|
||||
"traccar_server/geofences.json"
|
||||
)
|
||||
client.get_positions.return_value = load_json_array_fixture(
|
||||
"traccar_server/positions.json"
|
||||
)
|
||||
client.get_server.return_value = load_json_object_fixture(
|
||||
"traccar_server/server.json"
|
||||
)
|
||||
client.get_reports_events.return_value = load_json_array_fixture(
|
||||
"traccar_server/reports_events.json"
|
||||
)
|
||||
|
||||
yield client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry() -> MockConfigEntry:
|
||||
"""Mock a Traccar Server config entry."""
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
title="1.1.1.1:8082",
|
||||
data={
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_PORT: "8082",
|
||||
CONF_USERNAME: "test@example.org",
|
||||
CONF_PASSWORD: "ThisIsNotThePasswordYouAreL00kingFor",
|
||||
CONF_SSL: False,
|
||||
CONF_VERIFY_SSL: True,
|
||||
},
|
||||
options={
|
||||
CONF_CUSTOM_ATTRIBUTES: ["custom_attr_1"],
|
||||
CONF_EVENTS: ["device_moving"],
|
||||
CONF_MAX_ACCURACY: 5.0,
|
||||
CONF_SKIP_ACCURACY_FILTER_FOR: [],
|
||||
},
|
||||
)
|
||||
|
17
tests/components/traccar_server/fixtures/devices.json
Normal file
17
tests/components/traccar_server/fixtures/devices.json
Normal file
@ -0,0 +1,17 @@
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"name": "X-Wing",
|
||||
"uniqueId": "abc123",
|
||||
"status": "unknown",
|
||||
"disabled": false,
|
||||
"lastUpdate": "1970-01-01T00:00:00Z",
|
||||
"positionId": 0,
|
||||
"groupId": 0,
|
||||
"phone": null,
|
||||
"model": "1337",
|
||||
"contact": null,
|
||||
"category": "starfighter",
|
||||
"attributes": {}
|
||||
}
|
||||
]
|
10
tests/components/traccar_server/fixtures/geofences.json
Normal file
10
tests/components/traccar_server/fixtures/geofences.json
Normal file
@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Tatooine",
|
||||
"description": "A harsh desert world orbiting twin suns in the galaxy's Outer Rim",
|
||||
"area": "string",
|
||||
"calendarId": 0,
|
||||
"attributes": {}
|
||||
}
|
||||
]
|
24
tests/components/traccar_server/fixtures/positions.json
Normal file
24
tests/components/traccar_server/fixtures/positions.json
Normal file
@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"deviceId": 0,
|
||||
"protocol": "C-3PO",
|
||||
"deviceTime": "1970-01-01T00:00:00Z",
|
||||
"fixTime": "1970-01-01T00:00:00Z",
|
||||
"serverTime": "1970-01-01T00:00:00Z",
|
||||
"outdated": true,
|
||||
"valid": true,
|
||||
"latitude": 52.0,
|
||||
"longitude": 25.0,
|
||||
"altitude": 546841384638,
|
||||
"speed": 4568795,
|
||||
"course": 360,
|
||||
"address": "Mos Espa",
|
||||
"accuracy": 3.5,
|
||||
"network": {},
|
||||
"geofenceIds": [0],
|
||||
"attributes": {
|
||||
"custom_attr_1": "custom_attr_1_value"
|
||||
}
|
||||
}
|
||||
]
|
12
tests/components/traccar_server/fixtures/reports_events.json
Normal file
12
tests/components/traccar_server/fixtures/reports_events.json
Normal file
@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"type": "deviceMoving",
|
||||
"eventTime": "2019-08-24T14:15:22Z",
|
||||
"deviceId": 0,
|
||||
"positionId": 0,
|
||||
"geofenceId": 0,
|
||||
"maintenanceId": 0,
|
||||
"attributes": {}
|
||||
}
|
||||
]
|
21
tests/components/traccar_server/fixtures/server.json
Normal file
21
tests/components/traccar_server/fixtures/server.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"id": 0,
|
||||
"registration": true,
|
||||
"readonly": true,
|
||||
"deviceReadonly": true,
|
||||
"limitCommands": true,
|
||||
"map": null,
|
||||
"bingKey": null,
|
||||
"mapUrl": null,
|
||||
"poiLayer": null,
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"zoom": 0,
|
||||
"twelveHourFormat": true,
|
||||
"version": "99.99",
|
||||
"forceSettings": true,
|
||||
"coordinateFormat": null,
|
||||
"openIdEnabled": true,
|
||||
"openIdForce": true,
|
||||
"attributes": {}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
"""Test the Traccar Server config flow."""
|
||||
from collections.abc import Generator
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, patch
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
from pytraccar import TraccarException
|
||||
@ -29,7 +30,10 @@ from homeassistant.data_entry_flow import FlowResultType
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
async def test_form(
|
||||
hass: HomeAssistant,
|
||||
mock_traccar_api_client: Generator[AsyncMock, None, None],
|
||||
) -> None:
|
||||
"""Test we get the form."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
@ -37,19 +41,15 @@ async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.traccar_server.config_flow.ApiClient.get_server",
|
||||
return_value={"id": "1234"},
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "1.1.1.1:8082"
|
||||
@ -61,7 +61,7 @@ async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
CONF_SSL: False,
|
||||
CONF_VERIFY_SSL: True,
|
||||
}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert result["result"].state == config_entries.ConfigEntryState.LOADED
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -73,44 +73,40 @@ async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
)
|
||||
async def test_form_cannot_connect(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
side_effect: Exception,
|
||||
error: str,
|
||||
mock_traccar_api_client: Generator[AsyncMock, None, None],
|
||||
) -> None:
|
||||
"""Test we handle cannot connect error."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.traccar_server.config_flow.ApiClient.get_server",
|
||||
side_effect=side_effect,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
},
|
||||
)
|
||||
mock_traccar_api_client.get_server.side_effect = side_effect
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["errors"] == {"base": error}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.traccar_server.config_flow.ApiClient.get_server",
|
||||
return_value={"id": "1234"},
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
mock_traccar_api_client.get_server.side_effect = None
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_HOST: "1.1.1.1",
|
||||
CONF_USERNAME: "test-username",
|
||||
CONF_PASSWORD: "test-password",
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "1.1.1.1:8082"
|
||||
@ -122,27 +118,23 @@ async def test_form_cannot_connect(
|
||||
CONF_SSL: False,
|
||||
CONF_VERIFY_SSL: True,
|
||||
}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
assert result["result"].state == config_entries.ConfigEntryState.LOADED
|
||||
|
||||
|
||||
async def test_options(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_traccar_api_client: Generator[AsyncMock, None, None],
|
||||
) -> None:
|
||||
"""Test options flow."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={},
|
||||
)
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
assert mock_config_entry.options.get(CONF_MAX_ACCURACY) == 5.0
|
||||
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
||||
assert CONF_MAX_ACCURACY not in config_entry.options
|
||||
|
||||
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
||||
result = await hass.config_entries.options.async_init(mock_config_entry.entry_id)
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
@ -151,7 +143,7 @@ async def test_options(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert config_entry.options == {
|
||||
assert mock_config_entry.options == {
|
||||
CONF_MAX_ACCURACY: 2.0,
|
||||
CONF_EVENTS: [],
|
||||
CONF_CUSTOM_ATTRIBUTES: [],
|
||||
@ -234,10 +226,10 @@ async def test_options(
|
||||
)
|
||||
async def test_import_from_yaml(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
imported: dict[str, Any],
|
||||
data: dict[str, Any],
|
||||
options: dict[str, Any],
|
||||
mock_traccar_api_client: Generator[AsyncMock, None, None],
|
||||
) -> None:
|
||||
"""Test importing configuration from YAML."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -249,12 +241,10 @@ async def test_import_from_yaml(
|
||||
assert result["title"] == f"{data[CONF_HOST]}:{data[CONF_PORT]}"
|
||||
assert result["data"] == data
|
||||
assert result["options"] == options
|
||||
assert result["result"].state == config_entries.ConfigEntryState.LOADED
|
||||
|
||||
|
||||
async def test_abort_import_already_configured(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
) -> None:
|
||||
async def test_abort_import_already_configured(hass: HomeAssistant) -> None:
|
||||
"""Test abort for existing server while importing."""
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
@ -284,18 +274,12 @@ async def test_abort_import_already_configured(
|
||||
|
||||
async def test_abort_already_configured(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_traccar_api_client: Generator[AsyncMock, None, None],
|
||||
) -> None:
|
||||
"""Test abort for existing server."""
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "1.1.1.1", CONF_PORT: "8082"},
|
||||
)
|
||||
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
|
Loading…
x
Reference in New Issue
Block a user