Improve type hints in apple_tv tests (#118980)

This commit is contained in:
epenet 2024-06-06 17:44:22 +02:00 committed by GitHub
parent 837ee7c4fb
commit 5914ff0de8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 86 additions and 75 deletions

View File

@ -1,17 +1,18 @@
"""Fixtures for component.""" """Fixtures for component."""
from unittest.mock import patch from unittest.mock import AsyncMock, MagicMock, patch
from pyatv import conf from pyatv import conf
from pyatv.const import PairingRequirement, Protocol from pyatv.const import PairingRequirement, Protocol
from pyatv.support import http from pyatv.support import http
import pytest import pytest
from typing_extensions import Generator
from .common import MockPairingHandler, airplay_service, create_conf, mrp_service from .common import MockPairingHandler, airplay_service, create_conf, mrp_service
@pytest.fixture(autouse=True, name="mock_scan") @pytest.fixture(autouse=True, name="mock_scan")
def mock_scan_fixture(): def mock_scan_fixture() -> Generator[AsyncMock]:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
with patch("homeassistant.components.apple_tv.config_flow.scan") as mock_scan: with patch("homeassistant.components.apple_tv.config_flow.scan") as mock_scan:
@ -29,7 +30,7 @@ def mock_scan_fixture():
@pytest.fixture(name="dmap_pin") @pytest.fixture(name="dmap_pin")
def dmap_pin_fixture(): def dmap_pin_fixture() -> Generator[MagicMock]:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
with patch("homeassistant.components.apple_tv.config_flow.randrange") as mock_pin: with patch("homeassistant.components.apple_tv.config_flow.randrange") as mock_pin:
mock_pin.side_effect = lambda start, stop: 1111 mock_pin.side_effect = lambda start, stop: 1111
@ -37,7 +38,7 @@ def dmap_pin_fixture():
@pytest.fixture @pytest.fixture
def pairing(): def pairing() -> Generator[AsyncMock]:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
with patch("homeassistant.components.apple_tv.config_flow.pair") as mock_pair: with patch("homeassistant.components.apple_tv.config_flow.pair") as mock_pair:
@ -54,7 +55,7 @@ def pairing():
@pytest.fixture @pytest.fixture
def pairing_mock(): def pairing_mock() -> Generator[AsyncMock]:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
with patch("homeassistant.components.apple_tv.config_flow.pair") as mock_pair: with patch("homeassistant.components.apple_tv.config_flow.pair") as mock_pair:
@ -75,7 +76,7 @@ def pairing_mock():
@pytest.fixture @pytest.fixture
def full_device(mock_scan, dmap_pin): def full_device(mock_scan: AsyncMock, dmap_pin: MagicMock) -> AsyncMock:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
mock_scan.result.append( mock_scan.result.append(
create_conf( create_conf(
@ -96,7 +97,7 @@ def full_device(mock_scan, dmap_pin):
@pytest.fixture @pytest.fixture
def mrp_device(mock_scan): def mrp_device(mock_scan: AsyncMock) -> AsyncMock:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
mock_scan.result.extend( mock_scan.result.extend(
[ [
@ -116,7 +117,7 @@ def mrp_device(mock_scan):
@pytest.fixture @pytest.fixture
def airplay_with_disabled_mrp(mock_scan): def airplay_with_disabled_mrp(mock_scan: AsyncMock) -> AsyncMock:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
mock_scan.result.append( mock_scan.result.append(
create_conf( create_conf(
@ -136,7 +137,7 @@ def airplay_with_disabled_mrp(mock_scan):
@pytest.fixture @pytest.fixture
def dmap_device(mock_scan): def dmap_device(mock_scan: AsyncMock) -> AsyncMock:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
mock_scan.result.append( mock_scan.result.append(
create_conf( create_conf(
@ -156,7 +157,7 @@ def dmap_device(mock_scan):
@pytest.fixture @pytest.fixture
def dmap_device_with_credentials(mock_scan): def dmap_device_with_credentials(mock_scan: AsyncMock) -> AsyncMock:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
mock_scan.result.append( mock_scan.result.append(
create_conf( create_conf(
@ -176,7 +177,7 @@ def dmap_device_with_credentials(mock_scan):
@pytest.fixture @pytest.fixture
def airplay_device_with_password(mock_scan): def airplay_device_with_password(mock_scan: AsyncMock) -> AsyncMock:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
mock_scan.result.append( mock_scan.result.append(
create_conf( create_conf(
@ -191,7 +192,9 @@ def airplay_device_with_password(mock_scan):
@pytest.fixture @pytest.fixture
def dmap_with_requirement(mock_scan, pairing_requirement): def dmap_with_requirement(
mock_scan: AsyncMock, pairing_requirement: PairingRequirement
) -> AsyncMock:
"""Mock pyatv.scan.""" """Mock pyatv.scan."""
mock_scan.result.append( mock_scan.result.append(
create_conf( create_conf(

View File

@ -1,11 +1,12 @@
"""Test config flow.""" """Test config flow."""
from ipaddress import IPv4Address, ip_address from ipaddress import IPv4Address, ip_address
from unittest.mock import ANY, Mock, patch from unittest.mock import ANY, AsyncMock, MagicMock, Mock, patch
from pyatv import exceptions from pyatv import exceptions
from pyatv.const import PairingRequirement, Protocol from pyatv.const import PairingRequirement, Protocol
import pytest import pytest
from typing_extensions import Generator
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components import zeroconf from homeassistant.components import zeroconf
@ -45,19 +46,19 @@ RAOP_SERVICE = zeroconf.ZeroconfServiceInfo(
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def zero_aggregation_time(): def zero_aggregation_time() -> Generator[None]:
"""Prevent the aggregation time from delaying the tests.""" """Prevent the aggregation time from delaying the tests."""
with patch.object(config_flow, "DISCOVERY_AGGREGATION_TIME", 0): with patch.object(config_flow, "DISCOVERY_AGGREGATION_TIME", 0):
yield yield
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def use_mocked_zeroconf(mock_async_zeroconf): def use_mocked_zeroconf(mock_async_zeroconf: MagicMock) -> None:
"""Mock zeroconf in all tests.""" """Mock zeroconf in all tests."""
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def mock_setup_entry(): def mock_setup_entry() -> Generator[None]:
"""Mock setting up a config entry.""" """Mock setting up a config entry."""
with patch( with patch(
"homeassistant.components.apple_tv.async_setup_entry", return_value=True "homeassistant.components.apple_tv.async_setup_entry", return_value=True
@ -68,7 +69,8 @@ def mock_setup_entry():
# User Flows # User Flows
async def test_user_input_device_not_found(hass: HomeAssistant, mrp_device) -> None: @pytest.mark.usefixtures("mrp_device")
async def test_user_input_device_not_found(hass: HomeAssistant) -> None:
"""Test when user specifies a non-existing device.""" """Test when user specifies a non-existing device."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -85,7 +87,9 @@ async def test_user_input_device_not_found(hass: HomeAssistant, mrp_device) -> N
assert result2["errors"] == {"base": "no_devices_found"} assert result2["errors"] == {"base": "no_devices_found"}
async def test_user_input_unexpected_error(hass: HomeAssistant, mock_scan) -> None: async def test_user_input_unexpected_error(
hass: HomeAssistant, mock_scan: AsyncMock
) -> None:
"""Test that unexpected error yields an error message.""" """Test that unexpected error yields an error message."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -101,7 +105,8 @@ async def test_user_input_unexpected_error(hass: HomeAssistant, mock_scan) -> No
assert result2["errors"] == {"base": "unknown"} assert result2["errors"] == {"base": "unknown"}
async def test_user_adds_full_device(hass: HomeAssistant, full_device, pairing) -> None: @pytest.mark.usefixtures("full_device", "pairing")
async def test_user_adds_full_device(hass: HomeAssistant) -> None:
"""Test adding device with all services.""" """Test adding device with all services."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -149,9 +154,8 @@ async def test_user_adds_full_device(hass: HomeAssistant, full_device, pairing)
} }
async def test_user_adds_dmap_device( @pytest.mark.usefixtures("dmap_device", "dmap_pin", "pairing")
hass: HomeAssistant, dmap_device, dmap_pin, pairing async def test_user_adds_dmap_device(hass: HomeAssistant) -> None:
) -> None:
"""Test adding device with only DMAP service.""" """Test adding device with only DMAP service."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -183,8 +187,9 @@ async def test_user_adds_dmap_device(
} }
@pytest.mark.usefixtures("dmap_device", "dmap_pin")
async def test_user_adds_dmap_device_failed( async def test_user_adds_dmap_device_failed(
hass: HomeAssistant, dmap_device, dmap_pin, pairing hass: HomeAssistant, pairing: AsyncMock
) -> None: ) -> None:
"""Test adding DMAP device where remote device did not attempt to pair.""" """Test adding DMAP device where remote device did not attempt to pair."""
pairing.always_fail = True pairing.always_fail = True
@ -205,9 +210,8 @@ async def test_user_adds_dmap_device_failed(
assert result2["reason"] == "device_did_not_pair" assert result2["reason"] == "device_did_not_pair"
async def test_user_adds_device_with_ip_filter( @pytest.mark.usefixtures("dmap_device_with_credentials", "mock_scan")
hass: HomeAssistant, dmap_device_with_credentials, mock_scan async def test_user_adds_device_with_ip_filter(hass: HomeAssistant) -> None:
) -> None:
"""Test add device filtering by IP.""" """Test add device filtering by IP."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -225,9 +229,8 @@ async def test_user_adds_device_with_ip_filter(
@pytest.mark.parametrize("pairing_requirement", [(PairingRequirement.NotNeeded)]) @pytest.mark.parametrize("pairing_requirement", [(PairingRequirement.NotNeeded)])
async def test_user_pair_no_interaction( @pytest.mark.usefixtures("dmap_with_requirement", "pairing_mock")
hass: HomeAssistant, dmap_with_requirement, pairing_mock async def test_user_pair_no_interaction(hass: HomeAssistant) -> None:
) -> None:
"""Test pairing service without user interaction.""" """Test pairing service without user interaction."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -251,7 +254,7 @@ async def test_user_pair_no_interaction(
async def test_user_adds_device_by_ip_uses_unicast_scan( async def test_user_adds_device_by_ip_uses_unicast_scan(
hass: HomeAssistant, mock_scan hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test add device by IP-address, verify unicast scan is used.""" """Test add device by IP-address, verify unicast scan is used."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
@ -266,7 +269,8 @@ async def test_user_adds_device_by_ip_uses_unicast_scan(
assert str(mock_scan.hosts[0]) == "127.0.0.1" assert str(mock_scan.hosts[0]) == "127.0.0.1"
async def test_user_adds_existing_device(hass: HomeAssistant, mrp_device) -> None: @pytest.mark.usefixtures("mrp_device")
async def test_user_adds_existing_device(hass: HomeAssistant) -> None:
"""Test that it is not possible to add existing device.""" """Test that it is not possible to add existing device."""
MockConfigEntry(domain="apple_tv", unique_id="mrpid").add_to_hass(hass) MockConfigEntry(domain="apple_tv", unique_id="mrpid").add_to_hass(hass)
@ -282,8 +286,9 @@ async def test_user_adds_existing_device(hass: HomeAssistant, mrp_device) -> Non
assert result2["errors"] == {"base": "already_configured"} assert result2["errors"] == {"base": "already_configured"}
@pytest.mark.usefixtures("mrp_device")
async def test_user_connection_failed( async def test_user_connection_failed(
hass: HomeAssistant, mrp_device, pairing_mock hass: HomeAssistant, pairing_mock: AsyncMock
) -> None: ) -> None:
"""Test error message when connection to device fails.""" """Test error message when connection to device fails."""
pairing_mock.begin.side_effect = exceptions.ConnectionFailedError pairing_mock.begin.side_effect = exceptions.ConnectionFailedError
@ -310,8 +315,9 @@ async def test_user_connection_failed(
assert result2["reason"] == "setup_failed" assert result2["reason"] == "setup_failed"
@pytest.mark.usefixtures("mrp_device")
async def test_user_start_pair_error_failed( async def test_user_start_pair_error_failed(
hass: HomeAssistant, mrp_device, pairing_mock hass: HomeAssistant, pairing_mock: AsyncMock
) -> None: ) -> None:
"""Test initiating pairing fails.""" """Test initiating pairing fails."""
pairing_mock.begin.side_effect = exceptions.PairingError pairing_mock.begin.side_effect = exceptions.PairingError
@ -333,9 +339,8 @@ async def test_user_start_pair_error_failed(
assert result2["reason"] == "invalid_auth" assert result2["reason"] == "invalid_auth"
async def test_user_pair_service_with_password( @pytest.mark.usefixtures("airplay_device_with_password", "pairing_mock")
hass: HomeAssistant, airplay_device_with_password, pairing_mock async def test_user_pair_service_with_password(hass: HomeAssistant) -> None:
) -> None:
"""Test pairing with service requiring a password (not supported).""" """Test pairing with service requiring a password (not supported)."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -362,9 +367,8 @@ async def test_user_pair_service_with_password(
@pytest.mark.parametrize("pairing_requirement", [(PairingRequirement.Disabled)]) @pytest.mark.parametrize("pairing_requirement", [(PairingRequirement.Disabled)])
async def test_user_pair_disabled_service( @pytest.mark.usefixtures("dmap_with_requirement", "pairing_mock")
hass: HomeAssistant, dmap_with_requirement, pairing_mock async def test_user_pair_disabled_service(hass: HomeAssistant) -> None:
) -> None:
"""Test pairing with disabled service (is ignored with message).""" """Test pairing with disabled service (is ignored with message)."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -391,9 +395,8 @@ async def test_user_pair_disabled_service(
@pytest.mark.parametrize("pairing_requirement", [(PairingRequirement.Unsupported)]) @pytest.mark.parametrize("pairing_requirement", [(PairingRequirement.Unsupported)])
async def test_user_pair_ignore_unsupported( @pytest.mark.usefixtures("dmap_with_requirement", "pairing_mock")
hass: HomeAssistant, dmap_with_requirement, pairing_mock async def test_user_pair_ignore_unsupported(hass: HomeAssistant) -> None:
) -> None:
"""Test pairing with disabled service (is ignored silently).""" """Test pairing with disabled service (is ignored silently)."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -412,8 +415,9 @@ async def test_user_pair_ignore_unsupported(
assert result["reason"] == "setup_failed" assert result["reason"] == "setup_failed"
@pytest.mark.usefixtures("mrp_device")
async def test_user_pair_invalid_pin( async def test_user_pair_invalid_pin(
hass: HomeAssistant, mrp_device, pairing_mock hass: HomeAssistant, pairing_mock: AsyncMock
) -> None: ) -> None:
"""Test pairing with invalid pin.""" """Test pairing with invalid pin."""
pairing_mock.finish.side_effect = exceptions.PairingError pairing_mock.finish.side_effect = exceptions.PairingError
@ -440,8 +444,9 @@ async def test_user_pair_invalid_pin(
assert result2["errors"] == {"base": "invalid_auth"} assert result2["errors"] == {"base": "invalid_auth"}
@pytest.mark.usefixtures("mrp_device")
async def test_user_pair_unexpected_error( async def test_user_pair_unexpected_error(
hass: HomeAssistant, mrp_device, pairing_mock hass: HomeAssistant, pairing_mock: AsyncMock
) -> None: ) -> None:
"""Test unexpected error when entering PIN code.""" """Test unexpected error when entering PIN code."""
@ -468,8 +473,9 @@ async def test_user_pair_unexpected_error(
assert result2["errors"] == {"base": "unknown"} assert result2["errors"] == {"base": "unknown"}
@pytest.mark.usefixtures("mrp_device")
async def test_user_pair_backoff_error( async def test_user_pair_backoff_error(
hass: HomeAssistant, mrp_device, pairing_mock hass: HomeAssistant, pairing_mock: AsyncMock
) -> None: ) -> None:
"""Test that backoff error is displayed in case device requests it.""" """Test that backoff error is displayed in case device requests it."""
pairing_mock.begin.side_effect = exceptions.BackOffError pairing_mock.begin.side_effect = exceptions.BackOffError
@ -491,8 +497,9 @@ async def test_user_pair_backoff_error(
assert result2["reason"] == "backoff" assert result2["reason"] == "backoff"
@pytest.mark.usefixtures("mrp_device")
async def test_user_pair_begin_unexpected_error( async def test_user_pair_begin_unexpected_error(
hass: HomeAssistant, mrp_device, pairing_mock hass: HomeAssistant, pairing_mock: AsyncMock
) -> None: ) -> None:
"""Test unexpected error during start of pairing.""" """Test unexpected error during start of pairing."""
pairing_mock.begin.side_effect = Exception pairing_mock.begin.side_effect = Exception
@ -514,9 +521,8 @@ async def test_user_pair_begin_unexpected_error(
assert result2["reason"] == "unknown" assert result2["reason"] == "unknown"
async def test_ignores_disabled_service( @pytest.mark.usefixtures("airplay_with_disabled_mrp", "pairing")
hass: HomeAssistant, airplay_with_disabled_mrp, pairing async def test_ignores_disabled_service(hass: HomeAssistant) -> None:
) -> None:
"""Test adding device with only DMAP service.""" """Test adding device with only DMAP service."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
@ -573,9 +579,8 @@ async def test_zeroconf_unsupported_service_aborts(hass: HomeAssistant) -> None:
assert result["reason"] == "unknown" assert result["reason"] == "unknown"
async def test_zeroconf_add_mrp_device( @pytest.mark.usefixtures("mrp_device", "pairing")
hass: HomeAssistant, mrp_device, pairing async def test_zeroconf_add_mrp_device(hass: HomeAssistant) -> None:
) -> None:
"""Test add MRP device discovered by zeroconf.""" """Test add MRP device discovered by zeroconf."""
unrelated_result = await hass.config_entries.flow.async_init( unrelated_result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
@ -630,9 +635,8 @@ async def test_zeroconf_add_mrp_device(
} }
async def test_zeroconf_add_dmap_device( @pytest.mark.usefixtures("dmap_device", "dmap_pin", "pairing")
hass: HomeAssistant, dmap_device, dmap_pin, pairing async def test_zeroconf_add_dmap_device(hass: HomeAssistant) -> None:
) -> None:
"""Test add DMAP device discovered by zeroconf.""" """Test add DMAP device discovered by zeroconf."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=DMAP_SERVICE DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=DMAP_SERVICE
@ -660,7 +664,7 @@ async def test_zeroconf_add_dmap_device(
} }
async def test_zeroconf_ip_change(hass: HomeAssistant, mock_scan) -> None: async def test_zeroconf_ip_change(hass: HomeAssistant, mock_scan: AsyncMock) -> None:
"""Test that the config entry gets updated when the ip changes and reloads.""" """Test that the config entry gets updated when the ip changes and reloads."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain="apple_tv", unique_id="mrpid", data={CONF_ADDRESS: "127.0.0.2"} domain="apple_tv", unique_id="mrpid", data={CONF_ADDRESS: "127.0.0.2"}
@ -694,7 +698,7 @@ async def test_zeroconf_ip_change(hass: HomeAssistant, mock_scan) -> None:
async def test_zeroconf_ip_change_after_ip_conflict_with_ignored_entry( async def test_zeroconf_ip_change_after_ip_conflict_with_ignored_entry(
hass: HomeAssistant, mock_scan hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test that the config entry gets updated when the ip changes and reloads.""" """Test that the config entry gets updated when the ip changes and reloads."""
entry = MockConfigEntry( entry = MockConfigEntry(
@ -732,7 +736,7 @@ async def test_zeroconf_ip_change_after_ip_conflict_with_ignored_entry(
async def test_zeroconf_ip_change_via_secondary_identifier( async def test_zeroconf_ip_change_via_secondary_identifier(
hass: HomeAssistant, mock_scan hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test that the config entry gets updated when the ip changes and reloads. """Test that the config entry gets updated when the ip changes and reloads.
@ -774,7 +778,7 @@ async def test_zeroconf_ip_change_via_secondary_identifier(
async def test_zeroconf_updates_identifiers_for_ignored_entries( async def test_zeroconf_updates_identifiers_for_ignored_entries(
hass: HomeAssistant, mock_scan hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test that an ignored config entry gets updated when the ip changes. """Test that an ignored config entry gets updated when the ip changes.
@ -818,7 +822,8 @@ async def test_zeroconf_updates_identifiers_for_ignored_entries(
assert set(entry.data[CONF_IDENTIFIERS]) == {"airplayid", "mrpid"} assert set(entry.data[CONF_IDENTIFIERS]) == {"airplayid", "mrpid"}
async def test_zeroconf_add_existing_aborts(hass: HomeAssistant, dmap_device) -> None: @pytest.mark.usefixtures("dmap_device")
async def test_zeroconf_add_existing_aborts(hass: HomeAssistant) -> None:
"""Test start new zeroconf flow while existing flow is active aborts.""" """Test start new zeroconf flow while existing flow is active aborts."""
await hass.config_entries.flow.async_init( await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=DMAP_SERVICE DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=DMAP_SERVICE
@ -831,9 +836,8 @@ async def test_zeroconf_add_existing_aborts(hass: HomeAssistant, dmap_device) ->
assert result["reason"] == "already_in_progress" assert result["reason"] == "already_in_progress"
async def test_zeroconf_add_but_device_not_found( @pytest.mark.usefixtures("mock_scan")
hass: HomeAssistant, mock_scan async def test_zeroconf_add_but_device_not_found(hass: HomeAssistant) -> None:
) -> None:
"""Test add device which is not found with another scan.""" """Test add device which is not found with another scan."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=DMAP_SERVICE DOMAIN, context={"source": config_entries.SOURCE_ZEROCONF}, data=DMAP_SERVICE
@ -842,7 +846,8 @@ async def test_zeroconf_add_but_device_not_found(
assert result["reason"] == "no_devices_found" assert result["reason"] == "no_devices_found"
async def test_zeroconf_add_existing_device(hass: HomeAssistant, dmap_device) -> None: @pytest.mark.usefixtures("dmap_device")
async def test_zeroconf_add_existing_device(hass: HomeAssistant) -> None:
"""Test add already existing device from zeroconf.""" """Test add already existing device from zeroconf."""
MockConfigEntry(domain="apple_tv", unique_id="dmapid").add_to_hass(hass) MockConfigEntry(domain="apple_tv", unique_id="dmapid").add_to_hass(hass)
@ -853,7 +858,9 @@ async def test_zeroconf_add_existing_device(hass: HomeAssistant, dmap_device) ->
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
async def test_zeroconf_unexpected_error(hass: HomeAssistant, mock_scan) -> None: async def test_zeroconf_unexpected_error(
hass: HomeAssistant, mock_scan: AsyncMock
) -> None:
"""Test unexpected error aborts in zeroconf.""" """Test unexpected error aborts in zeroconf."""
mock_scan.side_effect = Exception mock_scan.side_effect = Exception
@ -865,7 +872,7 @@ async def test_zeroconf_unexpected_error(hass: HomeAssistant, mock_scan) -> None
async def test_zeroconf_abort_if_other_in_progress( async def test_zeroconf_abort_if_other_in_progress(
hass: HomeAssistant, mock_scan hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test discovering unsupported zeroconf service.""" """Test discovering unsupported zeroconf service."""
mock_scan.result = [ mock_scan.result = [
@ -912,8 +919,9 @@ async def test_zeroconf_abort_if_other_in_progress(
assert result2["reason"] == "already_in_progress" assert result2["reason"] == "already_in_progress"
@pytest.mark.usefixtures("pairing", "mock_zeroconf")
async def test_zeroconf_missing_device_during_protocol_resolve( async def test_zeroconf_missing_device_during_protocol_resolve(
hass: HomeAssistant, mock_scan, pairing, mock_zeroconf: None hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test discovery after service been added to existing flow with missing device.""" """Test discovery after service been added to existing flow with missing device."""
mock_scan.result = [ mock_scan.result = [
@ -970,8 +978,9 @@ async def test_zeroconf_missing_device_during_protocol_resolve(
assert result2["reason"] == "device_not_found" assert result2["reason"] == "device_not_found"
@pytest.mark.usefixtures("pairing", "mock_zeroconf")
async def test_zeroconf_additional_protocol_resolve_failure( async def test_zeroconf_additional_protocol_resolve_failure(
hass: HomeAssistant, mock_scan, pairing, mock_zeroconf: None hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test discovery with missing service.""" """Test discovery with missing service."""
mock_scan.result = [ mock_scan.result = [
@ -1030,8 +1039,9 @@ async def test_zeroconf_additional_protocol_resolve_failure(
assert result2["reason"] == "inconsistent_device" assert result2["reason"] == "inconsistent_device"
@pytest.mark.usefixtures("pairing", "mock_zeroconf")
async def test_zeroconf_pair_additionally_found_protocols( async def test_zeroconf_pair_additionally_found_protocols(
hass: HomeAssistant, mock_scan, pairing, mock_zeroconf: None hass: HomeAssistant, mock_scan: AsyncMock
) -> None: ) -> None:
"""Test discovered protocols are merged to original flow.""" """Test discovered protocols are merged to original flow."""
mock_scan.result = [ mock_scan.result = [
@ -1132,9 +1142,8 @@ async def test_zeroconf_pair_additionally_found_protocols(
assert result5["type"] is FlowResultType.CREATE_ENTRY assert result5["type"] is FlowResultType.CREATE_ENTRY
async def test_zeroconf_mismatch( @pytest.mark.usefixtures("pairing", "mock_zeroconf")
hass: HomeAssistant, mock_scan, pairing, mock_zeroconf: None async def test_zeroconf_mismatch(hass: HomeAssistant, mock_scan: AsyncMock) -> None:
) -> None:
"""Test the technically possible case where a protocol has no service. """Test the technically possible case where a protocol has no service.
This could happen in case of mDNS issues. This could happen in case of mDNS issues.
@ -1172,9 +1181,8 @@ async def test_zeroconf_mismatch(
# Re-configuration # Re-configuration
async def test_reconfigure_update_credentials( @pytest.mark.usefixtures("mrp_device", "pairing")
hass: HomeAssistant, mrp_device, pairing async def test_reconfigure_update_credentials(hass: HomeAssistant) -> None:
) -> None:
"""Test that reconfigure flow updates config entry.""" """Test that reconfigure flow updates config entry."""
config_entry = MockConfigEntry( config_entry = MockConfigEntry(
domain="apple_tv", unique_id="mrpid", data={"identifiers": ["mrpid"]} domain="apple_tv", unique_id="mrpid", data={"identifiers": ["mrpid"]}