Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

154 lines
5.0 KiB
Python
Raw Permalink Normal View History

2026-02-06 14:47:53 +04:00
"""Tests for Ghost sensors."""
from datetime import timedelta
from unittest.mock import AsyncMock
from aioghost.exceptions import GhostError
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from .conftest import NEWSLETTERS_DATA
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensor_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
mock_ghost_api: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Snapshot all Ghost sensor entities."""
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
async def test_newsletter_sensor_added_on_update(
hass: HomeAssistant,
mock_ghost_api: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test newsletter sensors are added after updates."""
await setup_integration(hass, mock_config_entry)
assert hass.states.get("sensor.test_ghost_monthly_subscribers") is None
mock_ghost_api.get_newsletters.return_value = [
*NEWSLETTERS_DATA,
{
"id": "nl3",
"name": "Monthly",
"status": "active",
"count": {"members": 300},
},
]
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
state = hass.states.get("sensor.test_ghost_monthly_subscribers")
assert state is not None
assert state.state == "300"
async def test_revenue_sensors_not_created_without_stripe(
hass: HomeAssistant, mock_ghost_api: AsyncMock, mock_config_entry
) -> None:
"""Test MRR/ARR sensors are not created when Stripe is not linked."""
# Return empty MRR/ARR data (no Stripe linked)
mock_ghost_api.get_mrr.return_value = {}
mock_ghost_api.get_arr.return_value = {}
await setup_integration(hass, mock_config_entry)
assert hass.states.get("sensor.test_ghost_mrr") is None
assert hass.states.get("sensor.test_ghost_arr") is None
async def test_newsletter_sensor_removed_when_stale(
2026-02-06 14:47:53 +04:00
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
2026-02-06 14:47:53 +04:00
mock_ghost_api: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test newsletter sensor is removed when newsletter disappears."""
2026-02-06 14:47:53 +04:00
await setup_integration(hass, mock_config_entry)
# Verify newsletter sensor exists
state = hass.states.get("sensor.test_ghost_weekly_subscribers")
assert state is not None
assert state.state == "800"
# Now return empty newsletters list
mock_ghost_api.get_newsletters.return_value = []
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
# Entity should be removed from state and registry
assert hass.states.get("sensor.test_ghost_weekly_subscribers") is None
assert entity_registry.async_get("sensor.test_ghost_weekly_subscribers") is None
async def test_newsletter_sensor_removed_on_reload(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_ghost_api: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test stale newsletter sensor is removed when integration reloads."""
await setup_integration(hass, mock_config_entry)
# Verify newsletter sensor exists
assert entity_registry.async_get("sensor.test_ghost_weekly_subscribers") is not None
# Unload the integration
await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Newsletter is gone when integration reloads
mock_ghost_api.get_newsletters.return_value = []
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
# Entity should be removed from registry
assert entity_registry.async_get("sensor.test_ghost_weekly_subscribers") is None
2026-02-06 14:47:53 +04:00
async def test_entities_unavailable_on_update_failure(
hass: HomeAssistant,
mock_ghost_api: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test entities become unavailable on update failure."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("sensor.test_ghost_total_members")
assert state is not None
assert state.state == "1025"
2026-02-06 14:47:53 +04:00
mock_ghost_api.get_site.side_effect = GhostError("Update failed")
freezer.tick(timedelta(minutes=5))
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
state = hass.states.get("sensor.test_ghost_total_members")
assert state is not None
assert state.state == STATE_UNAVAILABLE