Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests to development environment #223

Merged
merged 3 commits into from
Dec 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"editor.tabSize": 4,
"python.pythonPath": "/usr/bin/python3",
"python.analysis.autoSearchPaths": false,
"python.testing.pytestEnabled": true,
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.2
rev: v0.8.4
hooks:
- id: ruff
args:
Expand Down
105 changes: 75 additions & 30 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -1,35 +1,80 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Home Assistant on port 9126",
"type": "shell",
"command": "scripts/develop",
"problemMatcher": []
"version": "2.0.0",
"tasks": [
{
"label": "Run Home Assistant on port 9126",
"type": "shell",
"command": "scripts/develop",
"problemMatcher": []
},
{
"label": "Upgrade Home Assistant to latest (beta)",
"type": "shell",
"command": "scripts/upgrade",
"problemMatcher": []
},
{
"label": "Load Home Assistant from github - dev branch",
"type": "shell",
"command": "scripts/dev-branch",
"problemMatcher": []
},
{
"label": "Load specific version of Home Assistant",
"type": "shell",
"command": "scripts/specific-version",
"problemMatcher": []
},
{
"label": "Lint with ruff",
"type": "shell",
"command": "scripts/lint",
"problemMatcher": []
},
{
"label": "Pre-commit",
"type": "shell",
"command": "pre-commit run --show-diff-on-failure",
"group": {
"kind": "test",
"isDefault": true
},
{
"label": "Upgrade Home Assistant to latest (beta)",
"type": "shell",
"command": "scripts/upgrade",
"problemMatcher": []
"presentation": {
"reveal": "always",
"panel": "new"
},
{
"label": "Load Home Assistant from github - dev branch",
"type": "shell",
"command": "scripts/dev-branch",
"problemMatcher": []
"problemMatcher": []
},
{
"label": "Update syrupy snapshots",
"detail": "Update syrupy snapshots for a given integration.",
"type": "shell",
"command": "${command:python.interpreterPath} -m pytest ./tests/ --snapshot-update",
"dependsOn": [
"Compile English translations"
],
"group": {
"kind": "test",
"isDefault": true
},
{
"label": "Load specific version of Home Assistant",
"type": "shell",
"command": "scripts/specific-version",
"problemMatcher": []
"presentation": {
"reveal": "always",
"panel": "new"
},
{
"label": "Lint with ruff",
"type": "shell",
"command": "scripts/lint",
"problemMatcher": []
}
]
}
"problemMatcher": []
},
{
"label": "Lint with ruff",
"type": "shell",
"command": "scripts/lint",
"problemMatcher": []
}
],
"inputs": [
{
"id": "integrationName",
"type": "promptString",
"description": "For which integration should the task run?"
}
]
}
3 changes: 1 addition & 2 deletions custom_components/weatherlink/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,8 +543,7 @@ async def async_fetch():
api = entry.runtime_data.api
try:
async with asyncio.timeout(10):
res = await api.request("GET")
json_data = await res.json()
json_data = await api.get_data()
entry.runtime_data.current = json_data
return _preprocess(json_data)
except ClientResponseError as exc:
Expand Down
1 change: 0 additions & 1 deletion custom_components/weatherlink/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ async def async_step_user_3(
SelectOptionDict(value=str(stn[CONF_STATION_ID]), label=stn["station_name"])
for stn in (station_list_raw["stations"])
]

if user_input is None:
return self.async_show_form(
step_id="user_3",
Expand Down
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -438,3 +438,11 @@ fixture-parentheses = false

[tools.ruff.lint.mccabe]
max-complexity = 25

[tool.pytest.ini_options]
asyncio_mode = "auto"

[tool.coverage.run]
omit = [
"*/tests/*"
]
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ ruff==0.8.4
pre-commit==4.0.1
bumpver==2024.1130
urllib3>=1.26.5,<2
pytest-homeassistant-custom-component
13 changes: 13 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Stub - must be here."""

from pytest_homeassistant_custom_component.common import MockConfigEntry

from homeassistant.core import HomeAssistant


async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
"""Fixture for setting up the component."""
config_entry.add_to_hass(hass)

await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() # ? Needed ?
141 changes: 141 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
"""pytest fixtures."""

from collections.abc import Generator
from unittest.mock import patch

import pytest
from pytest_homeassistant_custom_component.common import load_fixture
from pytest_homeassistant_custom_component.syrupy import HomeAssistantSnapshotExtension
from syrupy import SnapshotAssertion

from homeassistant.core import HomeAssistant
from homeassistant.util.json import json_loads

# pylint: disable=redefined-outer-name


@pytest.fixture(autouse=True)
def auto_enable_custom_integrations(enable_custom_integrations):
"""Enable custom integrations defined in the test dir."""
return


@pytest.fixture
def data_file_name() -> str:
"""Filename for data fixture."""
return "strp81.json"


@pytest.fixture(name="load_default_station")
def load_default_station_fixture(data_file_name: str) -> dict:
"""Load data for default station."""
return json_loads(load_fixture(data_file_name))
# data = json_loads(load_fixture(data_file_name))
# result = data["GetSingleStationResult"]
# res = {}
# for sample in data["GetSingleStationResult"]["Samples"]:
# res[sample["Name"]] = sample
# result["Samples"] = res
# return result


@pytest.fixture(name="load_all_stations")
def load_all_stations_fixture() -> dict:
"""Load data for all stations."""
return json_loads(load_fixture("all_stations.json"))


@pytest.fixture(name="load_default_data")
def load_default_data_fixture() -> dict:
"""Load data for a station."""
return json_loads(load_fixture("strp81_current.json"))


@pytest.fixture(name="load_sensors")
def load_sensors_fixture() -> dict:
"""Load data for all stations."""
return json_loads(load_fixture("sensors.json"))


# data = json_loads(load_fixture("all_stations.json"))
# result = data["GetStationsResult"]["Stations"]
# return [Station(station_data) for station_data in result]


@pytest.fixture(name="bypass_get_data")
def bypass_get_data_fixture(
hass: HomeAssistant,
load_default_data: dict,
):
"""Skip calls to get data from API."""
with patch(
"custom_components.weatherlink.pyweatherlink.WLHubV2.get_data",
return_value=load_default_data,
):
yield


@pytest.fixture(name="bypass_get_station")
def bypass_get_station_fixture(
hass: HomeAssistant,
load_default_station: dict,
):
"""Skip calls to get data from API."""
with patch(
"custom_components.weatherlink.pyweatherlink.WLHubV2.get_station",
return_value=load_default_station,
):
yield


@pytest.fixture(name="bypass_get_all_sensors")
def bypass_get_all_sensors_fixture(
hass: HomeAssistant,
load_sensors: dict,
):
"""Skip calls to get data from API."""
with patch(
"custom_components.weatherlink.pyweatherlink.WLHubV2.get_all_sensors",
return_value=load_sensors,
):
yield


@pytest.fixture(name="bypass_get_all_stations")
def bypass_get_all_stations_fixture(
hass: HomeAssistant,
load_all_stations: dict,
):
"""Skip calls to get data from API."""
with patch(
"custom_components.weatherlink.pyweatherlink.WLHubV2.get_all_stations",
return_value=load_all_stations,
):
yield


@pytest.fixture
def entity_registry_enabled_by_default() -> Generator[None]:
"""Test fixture that ensures all entities are enabled in the registry."""
with patch(
"homeassistant.helpers.entity.Entity.entity_registry_enabled_default",
return_value=True,
):
yield


@pytest.fixture
def snapshot(snapshot: SnapshotAssertion) -> SnapshotAssertion:
"""Return snapshot assertion fixture with the Home Assistant extension."""
return snapshot.use_extension(HomeAssistantSnapshotExtension)


@pytest.fixture
def mock_api():
"""Mock api."""
with (
patch(
"custom_components.weatherlink.pyweatherlink.WLHubV2.get_data"
) as mock_api,
):
yield mock_api
9 changes: 9 additions & 0 deletions tests/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Constants for weatherlink tests."""

ENTRY_ID = "test"
MOCK_CONFIG_V2 = {
"api_version": "api_v2",
"api_key_v2": "apikey2",
"api_secret": "apisecret",
"station_id": "167531",
}
Loading
Loading