Reach full init test coverage in Minecraft Server (#102013)

* Add full init test coverage

* Fix patch location

* Use contant for test unique ID
This commit is contained in:
elmurato 2023-10-17 16:49:05 +02:00 committed by GitHub
parent 928086a9e5
commit 7cd376574e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 171 additions and 82 deletions

View file

@ -1,15 +1,24 @@
"""Tests for the Minecraft Server integration."""
from unittest.mock import patch
from mcstatus import JavaServer
import pytest
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.minecraft_server.api import MinecraftServerAddressError
from homeassistant.components.minecraft_server.const import DEFAULT_NAME, DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import CONF_ADDRESS, CONF_HOST, CONF_NAME, CONF_PORT
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from .const import TEST_ADDRESS, TEST_HOST, TEST_JAVA_DATA, TEST_PORT
from .const import (
TEST_ADDRESS,
TEST_CONFIG_ENTRY_ID,
TEST_HOST,
TEST_JAVA_STATUS_RESPONSE,
TEST_PORT,
)
from tests.common import MockConfigEntry
@ -27,11 +36,13 @@ SENSOR_KEYS = [
BINARY_SENSOR_KEYS = {"v1": "Status", "v2": "status"}
def create_v1_mock_config_entry(hass: HomeAssistant) -> int:
"""Create mock config entry."""
config_entry_v1 = MockConfigEntry(
@pytest.fixture
def v1_mock_config_entry() -> MockConfigEntry:
"""Create mock config entry with version 1."""
return MockConfigEntry(
domain=DOMAIN,
unique_id=TEST_UNIQUE_ID,
entry_id=TEST_CONFIG_ENTRY_ID,
data={
CONF_NAME: DEFAULT_NAME,
CONF_HOST: TEST_HOST,
@ -39,14 +50,10 @@ def create_v1_mock_config_entry(hass: HomeAssistant) -> int:
},
version=1,
)
config_entry_id = config_entry_v1.entry_id
config_entry_v1.add_to_hass(hass)
return config_entry_id
def create_v1_mock_device_entry(hass: HomeAssistant, config_entry_id: int) -> int:
"""Create mock device entry."""
def create_v1_mock_device_entry(hass: HomeAssistant, config_entry_id: str) -> str:
"""Create mock device entry with version 1."""
device_registry = dr.async_get(hass)
device_entry_v1 = device_registry.async_get_or_create(
config_entry_id=config_entry_id,
@ -61,9 +68,9 @@ def create_v1_mock_device_entry(hass: HomeAssistant, config_entry_id: int) -> in
def create_v1_mock_sensor_entity_entries(
hass: HomeAssistant, config_entry_id: int, device_entry_id: int
hass: HomeAssistant, config_entry_id: str, device_entry_id: str
) -> list[dict]:
"""Create mock sensor entity entries."""
"""Create mock sensor entity entries with version 1."""
sensor_entity_id_key_mapping_list = []
config_entry = hass.config_entries.async_get_entry(config_entry_id)
entity_registry = er.async_get(hass)
@ -86,9 +93,9 @@ def create_v1_mock_sensor_entity_entries(
def create_v1_mock_binary_sensor_entity_entry(
hass: HomeAssistant, config_entry_id: int, device_entry_id: int
hass: HomeAssistant, config_entry_id: str, device_entry_id: str
) -> dict:
"""Create mock binary sensor entity entry."""
"""Create mock binary sensor entity entry with version 1."""
config_entry = hass.config_entries.async_get_entry(config_entry_id)
entity_registry = er.async_get(hass)
entity_unique_id = f"{TEST_UNIQUE_ID}-{BINARY_SENSOR_KEYS['v1']}"
@ -108,53 +115,121 @@ def create_v1_mock_binary_sensor_entity_entry(
return binary_sensor_entity_id_key_mapping
async def test_entry_migration(hass: HomeAssistant) -> None:
async def test_setup_and_unload_entry(
hass: HomeAssistant, java_mock_config_entry: MockConfigEntry
) -> None:
"""Test successful entry setup and unload."""
java_mock_config_entry.add_to_hass(hass)
with patch(
"homeassistant.components.minecraft_server.api.JavaServer.lookup",
return_value=JavaServer(host=TEST_HOST, port=TEST_PORT),
), patch(
"homeassistant.components.minecraft_server.api.JavaServer.async_status",
return_value=TEST_JAVA_STATUS_RESPONSE,
):
assert await hass.config_entries.async_setup(java_mock_config_entry.entry_id)
await hass.async_block_till_done()
assert java_mock_config_entry.state == ConfigEntryState.LOADED
assert await hass.config_entries.async_unload(java_mock_config_entry.entry_id)
await hass.async_block_till_done()
assert not hass.data.get(DOMAIN)
assert java_mock_config_entry.state == ConfigEntryState.NOT_LOADED
async def test_setup_entry_failure(
hass: HomeAssistant, java_mock_config_entry: MockConfigEntry
) -> None:
"""Test failed entry setup."""
java_mock_config_entry.add_to_hass(hass)
with patch(
"homeassistant.components.minecraft_server.api.JavaServer.lookup",
side_effect=ValueError,
):
assert not await hass.config_entries.async_setup(
java_mock_config_entry.entry_id
)
await hass.async_block_till_done()
assert java_mock_config_entry.state == ConfigEntryState.SETUP_ERROR
async def test_setup_entry_not_ready(
hass: HomeAssistant, java_mock_config_entry: MockConfigEntry
) -> None:
"""Test entry setup not ready."""
java_mock_config_entry.add_to_hass(hass)
with patch(
"homeassistant.components.minecraft_server.api.JavaServer.lookup",
return_value=JavaServer(host=TEST_HOST, port=TEST_PORT),
), patch(
"homeassistant.components.minecraft_server.api.JavaServer.async_status",
return_value=OSError,
):
assert not await hass.config_entries.async_setup(
java_mock_config_entry.entry_id
)
await hass.async_block_till_done()
assert java_mock_config_entry.state == ConfigEntryState.SETUP_RETRY
async def test_entry_migration(
hass: HomeAssistant, v1_mock_config_entry: MockConfigEntry
) -> None:
"""Test entry migration from version 1 to 3, where host and port is required for the connection to the server."""
config_entry_id = create_v1_mock_config_entry(hass)
device_entry_id = create_v1_mock_device_entry(hass, config_entry_id)
v1_mock_config_entry.add_to_hass(hass)
device_entry_id = create_v1_mock_device_entry(hass, v1_mock_config_entry.entry_id)
sensor_entity_id_key_mapping_list = create_v1_mock_sensor_entity_entries(
hass, config_entry_id, device_entry_id
hass, v1_mock_config_entry.entry_id, device_entry_id
)
binary_sensor_entity_id_key_mapping = create_v1_mock_binary_sensor_entity_entry(
hass, config_entry_id, device_entry_id
hass, v1_mock_config_entry.entry_id, device_entry_id
)
# Trigger migration.
with patch(
"homeassistant.components.minecraft_server.api.MinecraftServer.__init__",
"homeassistant.components.minecraft_server.api.JavaServer.lookup",
side_effect=[
MinecraftServerAddressError, # async_migrate_entry
None, # async_migrate_entry
None, # async_setup_entry
ValueError, # async_migrate_entry
JavaServer(host=TEST_HOST, port=TEST_PORT), # async_migrate_entry
JavaServer(host=TEST_HOST, port=TEST_PORT), # async_setup_entry
],
return_value=None,
), patch(
"homeassistant.components.minecraft_server.api.MinecraftServer.async_get_data",
return_value=TEST_JAVA_DATA,
"homeassistant.components.minecraft_server.api.JavaServer.async_status",
return_value=TEST_JAVA_STATUS_RESPONSE,
):
assert await hass.config_entries.async_setup(config_entry_id)
assert await hass.config_entries.async_setup(v1_mock_config_entry.entry_id)
await hass.async_block_till_done()
migrated_config_entry = v1_mock_config_entry
# Test migrated config entry.
config_entry = hass.config_entries.async_get_entry(config_entry_id)
assert config_entry.unique_id is None
assert config_entry.data == {
assert migrated_config_entry.unique_id is None
assert migrated_config_entry.data == {
CONF_NAME: DEFAULT_NAME,
CONF_ADDRESS: TEST_ADDRESS,
}
assert config_entry.version == 3
assert migrated_config_entry.version == 3
assert migrated_config_entry.state == ConfigEntryState.LOADED
# Test migrated device entry.
device_registry = dr.async_get(hass)
device_entry = device_registry.async_get(device_entry_id)
assert device_entry.identifiers == {(DOMAIN, config_entry_id)}
assert device_entry.identifiers == {(DOMAIN, migrated_config_entry.entry_id)}
# Test migrated sensor entity entries.
entity_registry = er.async_get(hass)
for mapping in sensor_entity_id_key_mapping_list:
entity_entry = entity_registry.async_get(mapping["entity_id"])
assert entity_entry.unique_id == f"{config_entry_id}-{mapping['key']}"
assert (
entity_entry.unique_id
== f"{migrated_config_entry.entry_id}-{mapping['key']}"
)
# Test migrated binary sensor entity entry.
entity_entry = entity_registry.async_get(
@ -162,61 +237,70 @@ async def test_entry_migration(hass: HomeAssistant) -> None:
)
assert (
entity_entry.unique_id
== f"{config_entry_id}-{binary_sensor_entity_id_key_mapping['key']}"
== f"{migrated_config_entry.entry_id}-{binary_sensor_entity_id_key_mapping['key']}"
)
async def test_entry_migration_host_only(hass: HomeAssistant) -> None:
async def test_entry_migration_host_only(
hass: HomeAssistant, v1_mock_config_entry: MockConfigEntry
) -> None:
"""Test entry migration from version 1 to 3, where host alone is sufficient for the connection to the server."""
config_entry_id = create_v1_mock_config_entry(hass)
device_entry_id = create_v1_mock_device_entry(hass, config_entry_id)
create_v1_mock_sensor_entity_entries(hass, config_entry_id, device_entry_id)
create_v1_mock_binary_sensor_entity_entry(hass, config_entry_id, device_entry_id)
v1_mock_config_entry.add_to_hass(hass)
device_entry_id = create_v1_mock_device_entry(hass, v1_mock_config_entry.entry_id)
create_v1_mock_sensor_entity_entries(
hass, v1_mock_config_entry.entry_id, device_entry_id
)
create_v1_mock_binary_sensor_entity_entry(
hass, v1_mock_config_entry.entry_id, device_entry_id
)
# Trigger migration.
with patch(
"homeassistant.components.minecraft_server.api.MinecraftServer.__init__",
side_effect=[
None, # async_migrate_entry
None, # async_setup_entry
],
return_value=None,
"homeassistant.components.minecraft_server.api.JavaServer.lookup",
return_value=JavaServer(host=TEST_HOST, port=TEST_PORT),
), patch(
"homeassistant.components.minecraft_server.api.MinecraftServer.async_get_data",
return_value=TEST_JAVA_DATA,
"homeassistant.components.minecraft_server.api.JavaServer.async_status",
return_value=TEST_JAVA_STATUS_RESPONSE,
):
assert await hass.config_entries.async_setup(config_entry_id)
assert await hass.config_entries.async_setup(v1_mock_config_entry.entry_id)
await hass.async_block_till_done()
# Test migrated config entry.
config_entry = hass.config_entries.async_get_entry(config_entry_id)
assert config_entry.unique_id is None
assert config_entry.data == {
assert v1_mock_config_entry.unique_id is None
assert v1_mock_config_entry.data == {
CONF_NAME: DEFAULT_NAME,
CONF_ADDRESS: TEST_HOST,
}
assert config_entry.version == 3
assert v1_mock_config_entry.version == 3
assert v1_mock_config_entry.state == ConfigEntryState.LOADED
async def test_entry_migration_v3_failure(hass: HomeAssistant) -> None:
async def test_entry_migration_v3_failure(
hass: HomeAssistant, v1_mock_config_entry: MockConfigEntry
) -> None:
"""Test failed entry migration from version 2 to 3."""
config_entry_id = create_v1_mock_config_entry(hass)
device_entry_id = create_v1_mock_device_entry(hass, config_entry_id)
create_v1_mock_sensor_entity_entries(hass, config_entry_id, device_entry_id)
create_v1_mock_binary_sensor_entity_entry(hass, config_entry_id, device_entry_id)
v1_mock_config_entry.add_to_hass(hass)
device_entry_id = create_v1_mock_device_entry(hass, v1_mock_config_entry.entry_id)
create_v1_mock_sensor_entity_entries(
hass, v1_mock_config_entry.entry_id, device_entry_id
)
create_v1_mock_binary_sensor_entity_entry(
hass, v1_mock_config_entry.entry_id, device_entry_id
)
# Trigger migration.
with patch(
"homeassistant.components.minecraft_server.api.MinecraftServer.__init__",
"homeassistant.components.minecraft_server.api.JavaServer.lookup",
side_effect=[
MinecraftServerAddressError, # async_migrate_entry
MinecraftServerAddressError, # async_migrate_entry
ValueError, # async_migrate_entry
ValueError, # async_migrate_entry
],
return_value=None,
):
assert not await hass.config_entries.async_setup(config_entry_id)
assert not await hass.config_entries.async_setup(v1_mock_config_entry.entry_id)
await hass.async_block_till_done()
# Test config entry.
config_entry = hass.config_entries.async_get_entry(config_entry_id)
assert config_entry.version == 2
assert v1_mock_config_entry.version == 2
assert v1_mock_config_entry.state == ConfigEntryState.MIGRATION_ERROR