diff --git a/tests/components/syncthru/conftest.py b/tests/components/syncthru/conftest.py new file mode 100644 index 00000000000..e21a859ed98 --- /dev/null +++ b/tests/components/syncthru/conftest.py @@ -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 diff --git a/tests/components/syncthru/fixtures/state.json b/tests/components/syncthru/fixtures/state.json new file mode 100644 index 00000000000..2e4a6202700 --- /dev/null +++ b/tests/components/syncthru/fixtures/state.json @@ -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 +} diff --git a/tests/components/syncthru/test_config_flow.py b/tests/components/syncthru/test_config_flow.py index 727b95563cc..c551c94506e 100644 --- a/tests/components/syncthru/test_config_flow.py +++ b/tests/components/syncthru/test_config_flow.py @@ -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,