"""One-time firmware URLs and the address lamps use to reach Home Assistant.""" from __future__ import annotations from pathlib import Path from homeassistant.core import HomeAssistant from homeassistant.core_config import async_process_ha_core_config from homeassistant.exceptions import HomeAssistantError import pytest from pytest_homeassistant_custom_component.typing import ClientSessionGenerator from custom_components.ninlight.const import CONF_LAMP_BASE_URL from custom_components.ninlight.http import OtaRegistry, lamp_base_url from custom_components.ninlight.shared import DATA_SHARED from tests_unit.images import build_image def test_registry_keys_are_unique_and_43_characters() -> None: registry = OtaRegistry() keys = {registry.create(b"payload") for _ in range(50)} assert len(keys) == 50 assert all(len(key) == 43 for key in keys) assert len(registry) == 50 async def test_view_serves_only_its_own_registered_bytes( hass: HomeAssistant, hass_client_no_auth: ClientSessionGenerator, init_integration, firmware_dir: Path, ) -> None: registry = hass.data[DATA_SHARED].registry mine = build_image() other = build_image(version="0.3.9-rc1") key = registry.create(mine) other_key = registry.create(other) client = await hass_client_no_auth() response = await client.get(f"/api/ninlight/firmware/{key}") assert response.status == 200 assert await response.read() == mine other_response = await client.get(f"/api/ninlight/firmware/{other_key}") assert other_response.status == 200 assert await other_response.read() == other assert (await client.get("/api/ninlight/firmware/" + "x" * 43)).status == 404 registry.revoke(key) assert (await client.get(f"/api/ninlight/firmware/{key}")).status == 404 # revoking one key never touches another registered under a different key assert (await client.get(f"/api/ninlight/firmware/{other_key}")).status == 200 async def test_base_url_prefers_option(hass: HomeAssistant) -> None: await async_process_ha_core_config(hass, {"internal_url": "http://192.168.1.60:8123"}) assert ( lamp_base_url(hass, {CONF_LAMP_BASE_URL: "http://192.168.1.50:8123"}) == "http://192.168.1.50:8123" ) async def test_base_url_falls_back_to_internal_http_url(hass: HomeAssistant) -> None: await async_process_ha_core_config(hass, {"internal_url": "http://192.168.1.60:8123"}) assert lamp_base_url(hass, {}) == "http://192.168.1.60:8123" async def test_base_url_rejects_https(hass: HomeAssistant) -> None: await async_process_ha_core_config(hass, {"internal_url": "https://ha.local:8123"}) with pytest.raises(HomeAssistantError) as raised: lamp_base_url(hass, {}) assert raised.value.translation_key == "no_http_url" async def test_base_url_without_any_url(hass: HomeAssistant) -> None: with pytest.raises(HomeAssistantError) as raised: lamp_base_url(hass, {}) assert raised.value.translation_key == "no_http_url"