Improve Syncthru tests (#142338)

This commit is contained in:
Joost Lekkerkerker 2025-04-08 23:55:00 +02:00 committed by GitHub
parent 5d8c90ae0d
commit 528ca49368
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 232 additions and 51 deletions

View File

@ -0,0 +1,29 @@
"""Conftest for the SyncThru integration tests."""
from collections.abc import Generator
from unittest.mock import AsyncMock, patch
import pytest
from homeassistant.components.syncthru import DOMAIN
from tests.common import load_json_object_fixture
@pytest.fixture
def mock_syncthru() -> Generator[AsyncMock]:
"""Mock the SyncThru class."""
with (
patch(
"homeassistant.components.syncthru.SyncThru",
autospec=True,
) as mock_syncthru,
patch(
"homeassistant.components.syncthru.config_flow.SyncThru", new=mock_syncthru
),
):
client = mock_syncthru.return_value
client.model.return_value = "C430W"
client.is_unknown_state.return_value = False
client.raw.return_value = load_json_object_fixture("state.json", DOMAIN)
yield client

View File

@ -0,0 +1,182 @@
{
"status": {
"hrDeviceStatus": 3,
"status1": "",
"status2": "",
"status3": "",
"status4": ""
},
"identity": {
"model_name": "C430W",
"device_name": "Samsung C430W",
"host_name": "SEC84251907C415",
"location": "Living room",
"serial_num": "08HRB8GJ3F019DD",
"ip_addr": "192.168.0.251",
"ipv6_link_addr": "",
"mac_addr": "84:25:19:07:C4:15",
"admin_email": "",
"admin_name": "",
"admin_phone": "",
"customer_support": ""
},
"toner_black": {
"opt": 1,
"remaining": 8,
"cnt": 1176,
"newError": "C1-5110"
},
"toner_cyan": {
"opt": 1,
"remaining": 98,
"cnt": 25,
"newError": ""
},
"toner_magenta": {
"opt": 1,
"remaining": 98,
"cnt": 25,
"newError": ""
},
"toner_yellow": {
"opt": 1,
"remaining": 97,
"cnt": 27,
"newError": ""
},
"drum_black": {
"opt": 0,
"remaining": 44,
"newError": ""
},
"drum_cyan": {
"opt": 0,
"remaining": 100,
"newError": ""
},
"drum_magenta": {
"opt": 0,
"remaining": 100,
"newError": ""
},
"drum_yellow": {
"opt": 0,
"remaining": 100,
"newError": ""
},
"drum_color": {
"opt": 1,
"remaining": 44,
"newError": ""
},
"tray1": {
"opt": 1,
"paper_size1": 4,
"paper_size2": 0,
"paper_type1": 2,
"paper_type2": 0,
"paper_level": 0,
"capa": 150,
"newError": ""
},
"tray2": {
"opt": 0,
"paper_size1": 0,
"paper_size2": 0,
"paper_type1": 2,
"paper_type2": 0,
"paper_level": 0,
"capa": 0,
"newError": ""
},
"tray3": {
"opt": 0,
"paper_size1": 0,
"paper_size2": 0,
"paper_type1": 2,
"paper_type2": 0,
"paper_level": 0,
"capa": 0,
"newError": ""
},
"tray4": {
"opt": 0,
"paper_size1": 0,
"paper_size2": 0,
"paper_type1": 2,
"paper_type2": 0,
"paper_level": 0,
"capa": 0,
"newError": ""
},
"tray5": {
"opt": 0,
"paper_size1": 0,
"paper_size2": 0,
"paper_type1": 2,
"paper_type2": 0,
"paper_level": 0,
"capa": 0,
"newError": "0"
},
"mp": {
"opt": 0,
"paper_size1": 0,
"paper_size2": 0,
"paper_type1": 2,
"paper_type2": 0,
"paper_level": 0,
"capa": 0,
"newError": ""
},
"manual": {
"opt": 0,
"paper_size1": 0,
"paper_size2": 0,
"paper_type1": 2,
"paper_type2": 0,
"capa": 0,
"newError": ""
},
"GXI_INTRAY_MANUALFEEDING_TRAY_SUPPORT": 0,
"GXI_INSTALL_OPTION_MULTIBIN": 0,
"multibin": [0],
"outputTray": [[1, 50, ""]],
"capability": {
"hdd": {
"opt": 2,
"capa": 40
},
"ram": {
"opt": 65536,
"capa": 65536
},
"scanner": {
"opt": 0,
"capa": 0
}
},
"options": {
"hdd": 0,
"wlan": 1
},
"GXI_ACTIVE_ALERT_TOTAL": 2,
"GXI_ADMIN_WUI_HAS_DEFAULT_PASS": 0,
"GXI_SUPPORT_COLOR": 1,
"GXI_SYS_LUI_SUPPORT": 0,
"GXI_A3_SUPPORT": 0,
"GXI_TRAY2_MANDATORY_SUPPORT": 0,
"GXI_SWS_ADMIN_USE_AAA": 0,
"GXI_TONER_BLACK_VALID": 1,
"GXI_TONER_CYAN_VALID": 1,
"GXI_TONER_MAGENTA_VALID": 1,
"GXI_TONER_YELLOW_VALID": 1,
"GXI_IMAGING_BLACK_VALID": 1,
"GXI_IMAGING_CYAN_VALID": 1,
"GXI_IMAGING_MAGENTA_VALID": 1,
"GXI_IMAGING_YELLOW_VALID": 1,
"GXI_IMAGING_COLOR_VALID": 1,
"GXI_SUPPORT_PAPER_SETTING": 1,
"GXI_SUPPORT_PAPER_LEVEL": 0,
"GXI_SUPPORT_MULTI_PASS": 1
}

View File

@ -1,12 +1,10 @@
"""Tests for syncthru config flow."""
import re
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
from pysyncthru import SyncThruAPINotSupported
from homeassistant import config_entries
from homeassistant.components.syncthru.config_flow import SyncThru
from homeassistant.components.syncthru.const import DOMAIN
from homeassistant.const import CONF_NAME, CONF_URL
from homeassistant.core import HomeAssistant
@ -21,7 +19,6 @@ from homeassistant.helpers.service_info.ssdp import (
)
from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker
FIXTURE_USER_INPUT = {
CONF_URL: "http://192.168.1.2/",
@ -29,25 +26,7 @@ FIXTURE_USER_INPUT = {
}
def mock_connection(aioclient_mock):
"""Mock syncthru connection."""
aioclient_mock.get(
re.compile("."),
text="""
{
\tstatus: {
\thrDeviceStatus: 2,
\tstatus1: " Sleeping... "
\t},
\tidentity: {
\tserial_num: "000000000000000",
\t}
}
""",
)
async def test_show_setup_form(hass: HomeAssistant) -> None:
async def test_show_setup_form(hass: HomeAssistant, mock_syncthru: AsyncMock) -> None:
"""Test that the setup form is served."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=None
@ -58,7 +37,7 @@ async def test_show_setup_form(hass: HomeAssistant) -> None:
async def test_already_configured_by_url(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant, mock_syncthru: AsyncMock
) -> None:
"""Test we match and update already configured devices by URL."""
@ -69,7 +48,6 @@ async def test_already_configured_by_url(
title="Already configured",
unique_id=udn,
).add_to_hass(hass)
mock_connection(aioclient_mock)
result = await hass.config_entries.flow.async_init(
DOMAIN,
@ -83,44 +61,39 @@ async def test_already_configured_by_url(
assert result["result"].unique_id == udn
async def test_syncthru_not_supported(hass: HomeAssistant) -> None:
async def test_syncthru_not_supported(
hass: HomeAssistant, mock_syncthru: AsyncMock
) -> None:
"""Test we show user form on unsupported device."""
with patch.object(SyncThru, "update", side_effect=SyncThruAPINotSupported):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data=FIXTURE_USER_INPUT,
)
mock_syncthru.update.side_effect = SyncThruAPINotSupported
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data=FIXTURE_USER_INPUT,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {CONF_URL: "syncthru_not_supported"}
async def test_unknown_state(hass: HomeAssistant) -> None:
async def test_unknown_state(hass: HomeAssistant, mock_syncthru: AsyncMock) -> None:
"""Test we show user form on unsupported device."""
with (
patch.object(SyncThru, "update"),
patch.object(SyncThru, "is_unknown_state", return_value=True),
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data=FIXTURE_USER_INPUT,
)
mock_syncthru.is_unknown_state.return_value = True
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_USER},
data=FIXTURE_USER_INPUT,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {CONF_URL: "unknown_state"}
async def test_success(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
async def test_success(hass: HomeAssistant, mock_syncthru: AsyncMock) -> None:
"""Test successful flow provides entry creation data."""
mock_connection(aioclient_mock)
with patch(
"homeassistant.components.syncthru.async_setup_entry", return_value=True
) as mock_setup_entry:
@ -129,18 +102,15 @@ async def test_success(
context={"source": config_entries.SOURCE_USER},
data=FIXTURE_USER_INPUT,
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"][CONF_URL] == FIXTURE_USER_INPUT[CONF_URL]
assert len(mock_setup_entry.mock_calls) == 1
async def test_ssdp(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker) -> None:
async def test_ssdp(hass: HomeAssistant, mock_syncthru: AsyncMock) -> None:
"""Test SSDP discovery initiates config properly."""
mock_connection(aioclient_mock)
url = "http://192.168.1.2/"
result = await hass.config_entries.flow.async_init(
DOMAIN,